Mos*_*evi 5 c# generics overload-resolution
请考虑以下代码:
public class Tests
{
    public void Test()
    {
        Assert.AreEqual("Int", DoSomething(1));
    }
    public static string DoSomething<T>(T value)
    {
        return "Generic";
    }
    public static string DoSomething(int value)
    {
        return "Int";
    }
}
正如所料,将调用非泛型的DoSomething方法.现在考虑以下修改:
public class Tests
{
    public void Test()
    {
        Assert.AreEqual("Int", DoSomething(1));
    }
    public static string DoSomething<T>(T value)
    {
        return "Generic";
    }
    public static string DoSomething<T>(int value)
    {
        return "Int";
    }
}
我唯一改变的是将T类型参数添加到第二个重载,从而使其成为通用的.请注意,不使用type参数.
该修改导致调用第一个DoSomething方法.为什么?编译器具有所需的所有信息,以便选择第二种方法.
你能解释为什么,甚至更好地指出我解释这种行为的C#规范部分?
Jon*_*eet 10
在你的调用中,你没有指定一个类型参数 - 所以编译器必须推断出它的类型T.它不能为您的第二个方法执行此操作,因为声明的参数中从未提及type参数.因此,该过载不适用,并被忽略.
如果为调用指定了类型参数,例如任何一个
DoSomething<int>(1)
DoSomething<object>(1)
DoSomething<string>(1)
...然后在所有情况下都会调用第二个重载.
在构造候选方法集时,从C#5规范的第7.6.5.1节(方法调用):
- 如果F是通用的且M没有类型参数列表,则F是以下情况的候选者:
- 类型推断(第7.5.2节)成功,推断出调用的类型参数列表,以及
- 一旦推断的类型参数替换相应的方法类型参数,F的参数列表中的所有构造类型都满足它们的约束(§4.4.4),并且F的参数列表适用于A(§7.5.3.1) ).
类型推断并不成功,第二个方法是不在候选集,所以通过时间我们得到真正的重载决议,该组只是在一个单一的方法(第一个).
| 归档时间: | 
 | 
| 查看次数: | 276 次 | 
| 最近记录: |