MakeGenericMethod/MakeGenericType on Xamarin.iOS

本文关键字:Xamarin iOS on MakeGenericType MakeGenericMethod | 更新日期: 2023-09-27 18:11:29

我试图弄清楚从Xamarin部署到iOS时的限制真正意味着什么。

http://developer.xamarin.com/guides/ios/advanced_topics/limitations/

我的印象是你没有JIT,因此任何MakeGenericMethod或MakeGenericType都不能工作,因为这需要JIT编译。

我也明白,当在模拟器上运行时,这些限制不适用,因为模拟器不是在完整的AOT(提前)模式下运行。

设置我的Mac以便我可以部署到我的手机后,我希望下面的测试在实际设备(iPhone)上运行时失败。

    [Test]
    public void InvokeGenericMethod()
    {
        var method = typeof(SampleTests).GetMethod ("SomeGenericMethod");
        var closedMethod = method.MakeGenericMethod (GetTypeArgument());
        closedMethod.Invoke (null, new object[]{42});
    }
    public static void SomeGenericMethod<T>(T value)
    {
    }

    private Type GetTypeArgument()
    {
        return typeof(int);
    }
问题是它完成得很成功,我真的不明白为什么。这段代码不需要JIT编译吗?

为了"使它中断",我还用MakeGenericType做了一个测试。

    [Test]
    public void InvokeGenericType()
    {
        var type = typeof(SomeGenericClass<>).MakeGenericType (typeof(string));
        var instance = Activator.CreateInstance (type);
        var method = type.GetMethod ("Execute");
        method.Invoke (instance, new object[]{"Test"});
    }

public class SomeGenericClass<T>
{
    public void Execute(T value)
    {
    }
}

在没有JIT的情况下如何工作?

MakeGenericMethod/MakeGenericType on Xamarin.iOS

为了使代码失败,进入iOS项目选项,选择"iOS Build"并将" linkker Behavior:"更改为"Link all assemblies"。运行代码将导致异常,并且它的类型为XXX类型的默认构造函数未找到。

现在,在代码中引用SomeGenericClass{string},该方法将正常运行。添加的两行会导致编译器在二进制文件中包含SomeGenericClass{string}。注意,这些行可以在编译成二进制文件的应用程序中的任何地方,它们不必在同一个函数中。

    public void InvokeGenericType()
    {
        // comment out the two lines below to make the code fail
        var strClass = new SomeGenericClass<string>();
        strClass.Execute("Test");
        var type = typeof(SomeGenericClass<>).MakeGenericType (typeof(string));
        var instance = Activator.CreateInstance (type);
        var method = type.GetMethod ("Execute");
        method.Invoke (instance, new object[]{"Test"});
    }