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
    No fields configured for issues without a type.

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions