我试图弄清楚从Xamarin部署iOS时的限制是什么意义。
http://developer.xamarin.com/guides/ios/advanced_topics/limitations/
我的印象是你没有JIT,因此任何MakeGenericMethod或MakeGenericType都不会起作用,因为这需要JIT编译。
另外我明白在模拟器上运行时,这些限制不适用,因为模拟器没有在完整的AOT(Ahead of Time)模式下运行。
设置我的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编译吗?
努力让它突破&#34; ,我也用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,这怎么办?
我错过了什么吗?
答案 0 :(得分:2)
为了使代码失败,请转到iOS项目选项,选项卡“iOS Build”并将“链接器行为:”更改为“链接所有程序集”。运行代码将导致异常,并且它将是类型为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"});
}