Xamarin是一个完全提前编译.NET代码的系统(AOT),用于禁止数据执行的平台,因此不能拥有JIT。这个问题不是关于Xamarin,而是关于它的文档所做的断言。它声明here:
通用虚方法支持是有限的,不可能静态地确定在所有情况下将调用哪种方法,因此编译器可能会遗漏一些方法。
我可能会弄错,但他们似乎暗示通过静态分析对这里可能发生的事情进行广泛的陈述,而不仅仅是他们选择在自己的软件中实施的内容。
正如Hans Passant恰当地指出的那样,他们给出的例子实际上并没有证明他们所指的问题,所以我把它排除在外。
因此,除了这些绝对棘手的特殊情况:
反射;
动态生成的代码(无论如何都是非法的);
涉及值类型的类型参数中的病态循环引用;以及
外国集会;
什么会使AOT编译器无法处理虚拟泛型方法案例?
答案 0 :(得分:2)
这个例子只是borken,根本没有证明问题。虚方法中隐含的是编译器无法可靠地确定可以调用该方法的调用站点。这是泛型方法的问题,因为编译器必须创建它的多个版本。
需要一个版本来处理任何引用类型,特别是注释“使用带有引用类型的通用虚方法(如Object或String)通常是安全的,因为编译器总是编译一个那个可以处理的版本“。换句话说,它可能只是盲目地产生那个。
麻烦制造者是T是值类型的版本。必须为每个不同的值类型编译一个不同的具体方法。由于编译器无法猜测调用站点,因此也无法查看必须为其创建方法的值类型。由于结构类型和具有多个类型参数的方法,盲目地生成它们是不可行的。
答案 1 :(得分:0)
我从根本上同意你的分析。
Xamarin和类似工具可以按相反的顺序进行此操作,可以说,通过包含实例类型和虚拟方法签名的每个可想到的组合,然后继续仅删除可证明不需要的组合。
但是,他们可能尝试过这样做,并发现生成的代码对于复杂的对象层次结构确实会变得非常大/慢。