Skip to content

[NativeAOT][iOS] App Hangs/Freezes with Static Virtual Properties in Interfaces on .NET 9 #113423

@vyacheslav-volkov

Description

@vyacheslav-volkov

Description

When migrating an iOS project from .NET 8 NativeAOT to .NET 9 NativeAOT, the application hangs (appears to deadlock) without throwing any exceptions or generating error logs. After significant troubleshooting, the issue was traced to the use of a static virtual property within an interface. In .NET 9, the following simplified code consistently reproduces the hang, whereas it works as expected under .NET 8.

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
    public override UIWindow? Window { get; set; }

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        Window = new UIWindow(UIScreen.MainScreen.Bounds);
        Window.RootViewController = new MainController();
        Window.MakeKeyAndVisible();
        return true;
    }
}

public class Test : ITestInterface<Test>
{
    public static bool Flag => true;
}

public interface ITestInterface<in TRequest>
    where TRequest : ITestInterface<TRequest>
{
    protected static virtual bool Flag => false;

    public static virtual void Invoke(TRequest request)
    {
        if (TRequest.Flag)
            Console.WriteLine("flag=true");
    }
}

public class MainController : UIViewController
{
    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        Console.WriteLine("Begin Invoke");
        Invoke(new Test());
        Console.WriteLine("End Invoke");
    }

    public static void Invoke<TRequest>(TRequest request)
        where TRequest : ITestInterface<TRequest> 
            => TRequest.Invoke(request);
}

Reproduction Steps

  • Create a new iOS project targeting .NET 9 with the code from the issue.
  • Run the application in NativeAOT mode

Expected behavior

The application should start normally and display the log messages:

Begin Invoke
flag=true
End Invoke

Actual behavior

The application hangs (freezes) with no console output beyond Begin Invoke, and no exceptions are thrown. Execution never reaches flag=true or End Invoke.

Regression?

This issue does not appear on .NET 8; it only occurs after upgrading to .NET 9.

Known Workarounds

If I change the property to abstract, it works.
If I change the property to method protected static virtual bool GetFlag() => false;, it works.

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions