generics和从差异类调用重载方法 – 优先级问题
首先,抱歉标题,但我想不出更好的事情……
我的问题可以通过简单的代码示例呈现:
public static class Test { public static int GetInt(T source) { return Convert.ToInt32(source); } } public static class Convert { public static int ToInt32(byte source) { return 30; } public static int ToInt32(object source) { return 10; } }
为什么Console.WriteLine(Test.GetInt(20));
打印10
,而不是30
?
我一直认为.NET中的generics在运行时由JIT解决。 为什么然后抖动不够智能,发现有ToInt32(byte)
方法,这适合我们的byte
参数类型?
此行为使得Convert
静态类方法在简单类型的装箱/拆箱操作中调用结果。
编译器必须在编译时决定选择哪种方法。 它不会发出任何代码来在运行时决定选择哪两个重载。 因为您没有向C#编译器提供任何证据certificateGetInt(T source)
仅适用于byte
结构,所以编译器必须选择另一个重载。
或者让我以不同的角度来看:如果删除ToInt32(object)
重载,程序将无法编译。
编译器在编译时决定执行哪个方法。
我通过Reflector了解IL代码并发现了 –
.method public hidebysig static int32 GetInt(!T source) cil managed { .maxstack 1 .locals init ( [0] int32 CS$1$0000) L_0000: nop L_0001: ldarg.0 L_0002: box !T L_0007: call int32 ConsoleApplication1.Convert::ToInt32(object) <-- HERE L_000c: stloc.0 L_000d: br.s L_000f L_000f: ldloc.0 L_0010: ret }
正如Jon Skeet 在这里所提到的,你可以使用dynamic
调用byte方法,它在执行时而不是编译时提供类型信息。
public static class Test { public static int GetInt(T source) { dynamic dynamicSource = source; return Convert.ToInt32(dynamicSource ); } }