首先,抱歉标题,但我想不出更好的事情......
我的问题可以通过简单的代码示例来呈现:
public static class Test<T>
{
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<byte>.GetInt(20));
打印10
而不是30
?
我一直认为.NET中的泛型在运行时由JIT解决。为什么然后抖动不够智能,找出适合我们ToInt32(byte)
参数类型的byte
方法?
此行为使Convert
静态类方法调用导致简单类型的装箱/拆箱操作。
答案 0 :(得分:7)
编译器必须在编译时决定选择哪种方法。它不会发出任何代码来在运行时决定选择哪两个重载。因为您没有向C#编译器提供任何证据GetInt(T source)
仅适用于byte
结构,所以编译器必须选择其他重载。
或者让我以不同的角度看待它:如果删除ToInt32(object)
重载,程序将无法编译。
答案 1 :(得分:0)
编译器在编译时决定执行哪种方法。
我通过反射器了解 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 here所述,您可以使用dynamic
调用byte方法,public static class Test<T>
{
public static int GetInt(T source)
{
dynamic dynamicSource = source;
return Convert.ToInt32(dynamicSource );
}
}
在执行时而不是编译时提供类型信息。
{{1}}