泛型和从差异类调用重载方法 - 优先级问题

时间:2013-08-15 13:33:18

标签: c# generics overloading

首先,抱歉标题,但我想不出更好的事情......

我的问题可以通过简单的代码示例来呈现:

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静态类方法调用导致简单类型的装箱/拆箱操作。

2 个答案:

答案 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}}