7

Xamarin 是一个系统,它为不允许数据执行的平台完全提前 (AOT) 编译 .NET 代码,因此不能有 JIT。这个问题不是关于 Xamarin,而是关于它的文档所做的断言。它在这里声明:

通用虚拟方法支持是有限的,不可能静态确定在所有情况下都会调用什么方法,因此编译器可能会忽略其中的一些。

我可能弄错了,但他们似乎暗示了通过静态分析在这里可能实现的广泛陈述,而不仅仅是他们选择在自己的软件中实现的内容。

正如 Hans Passant 恰当地指出的那样,他们给出的例子实际上并没有证明他们所指的问题,所以我将其排除在外。

所以,除了这些绝对棘手的特殊情况:

  • 反射;

  • 动态生成的代码(在这种情况下无论如何都是非法的);

  • 涉及值类型的类型参数中的病态循环引用;和

  • 外国集会;

什么会使 AOT 编译器无法处理虚拟泛型方法案例?

4

2 回答 2

2

这个例子很糟糕,根本没有说明问题。隐含在虚方法中的是编译器无法可靠地确定该方法可能从哪些调用站点被调用。这是泛型方法的一个问题,因为编译器必须创建它的多个版本。

需要一个版本来处理任何引用类型,特别是在“使用具有引用类型(如 Object 或 String)的泛型虚方法通常是安全的,因为编译器总是编译可以处理的版本”的备注中特别提到。或者换句话说,它可能只是盲目地生成那个。

麻烦制造者是 T 是值类型的版本。必须为每个不同的值类型编译一个不同的具体方法。由于编译器无法猜测调用站点,它也无法看到它必须为哪些值类型创建方法。由于结构类型和具有多个类型参数的方法,盲目地生成它们是不可行的。

于 2013-11-12T03:56:52.360 回答
0

我基本同意你的分析。

Xamarin 和类似工具可以以相反的顺序进行此操作,可以说,通过包括实例类型和虚拟方法签名的每个可能的组合,然后继续仅删除可证明不需要的那些。

不过,他们可能尝试过,并发现生成的代码对于复杂的对象层次结构确实会变得非常大/慢。

于 2013-11-11T23:36:37.273 回答