O Native AOT é incrível, isso já sabemos, mas apesar da microsoft não fornecer suporte para WinForms e WPF, já disseram que isso é perfeitamente possível, embora mais facil no Winforms que WPF, apenas não estão nos planos (ainda sim fizeram experimentos com WinForms, que é bem mais fácil, você pode conferir aqui ). Essas últimas semanas eu venho trabalhando em alguns projetos com Native AOT e essa falta de suporte à aplicações visuais realmente me incomodou, pois estou realmente maravilhado com os benefícios de uma linguagem compilada no c#, mas ok, a vida continua.

Porque WinForms é mais fácil?

Se você conferiu as melhorias feitas para WinForms no .NET 7, percebeu que já fizeram experimentos com WinForms, mas não mencionaram os testes com WPF, isto é porquê WPF usa muito mais reflexão, tornando muito mais difícil e trabalhoso ter primeiros resultados funcionais. No .NET 5, foram substituidas as interoperabilidades COM integradas selecionadas do Windows Forms por ComWrappers, assim o COM integrado fica completamente desativado em cenários de trimming/Native AOT

Realmente é possível compilar WinForms com Native AOT?

Sim, mas com resalvas. Oficialmente não é suportado, mas a propria microsoft menciona os esforços de @kant2002, que disponibilizou a biblioteca WinFormsComInterop, que nos permite compilar Native AOT. Kant afirma que com o tempo essa biblioteca vai morrer, ao ser adicionado suporte oficial ao WinForms (sinceramente espero que ocorra logo). De qualquer forma, ainda é muito melhor que usar uma build beta de Avalonia em produção, que é o que estou fazendo com alguns pojetos. Para finalizar, você pode usar Native AOT + WinForms, mas ainda há varios problemas durante o desenvolvimento que terá que resolver por conta própria por enquanto, mas já é possível fazer muita coisa com isso.

Passo a passo

Com o seu projeto WinForms .NET 7 já criado:

using System.Runtime.InteropServices;

namespace WinFormsAOT_example
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            ComWrappers.RegisterForMarshalling(WinFormsComInterop.WinFormsComWrappers.Instance);
            ApplicationConfiguration.Initialize();
            Application.Run(new Form1());
        }
    }
}
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net7.0-windows</TargetFramework>
    <Nullable>enable</Nullable>
    <UseWindowsForms>true</UseWindowsForms>
    <ImplicitUsings>enable</ImplicitUsings>
    <PublishAot>true</PublishAot>
    <_SuppressWinFormsTrimError>true</_SuppressWinFormsTrimError>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="WinFormsComInterop" Version="0.4.3" />
  </ItemGroup>

</Project>
Você pode baixar aqui o projeto de exemplo