选择哪种C#方法重载?

为什么两个重载都匹配时调用generics方法?

public static void method1(object obj) { Console.WriteLine("Object"); } public static void method1(T t) { Console.WriteLine("Type T"); } public static void Main(String args[]) { method1("xyz"); //Will print "Type T"; } 

这里不应该有任何冲突,对吧?

通过选择最具体的过载来解决过载问题。 在这种情况下, method1(string)method1(object)更具体,因此选择了重载。

C#规范的7.4.2节有详细说明 。

如果要选择特定的重载,可以通过将参数显式地转换为所需的类型来实现。 以下将调用method1(object)重载而不是泛​​型:

 method1((object)"xyz"); 

在某些情况下,编译器不会知道要选择哪个重载,例如:

 void method2(string x, object y); void method2(object x, string y); method2("xyz", "abc"); 

在这种情况下,编译器不知道要选择哪个重载,因为两个重载都没有明显优于另一个(它不知道哪个字符串隐式地向下转换为对象)。 所以它会发出编译器错误。

C#总是会选择最具体的方法。

编译时

 method1("xyz"); 

它将查找具有指定名称的所有方法,然后尝试匹配参数。 编译器将选择最具体的方法,在这种情况下它会更喜欢

 method1(string s) 

过度

 method1(T t) with T = string 

最后

 method1(object o) 

请注意@ Erik对编译器无法确定的示例的出色答案。

因为您已经将T作为参数传递,所以您不需要输入method1("xyz"); 你可以去method1("xyz"); ,.Net已经知道它是一个字符串。 如果你有方法1那么这将是一个不同的故事。

此外,由于method1(object obj)不接受字符串作为参数,它将首先支持generics函数,它可以推断T.如果你要将method1(object obj)更改为method1(string obj)它将首先支持它然后通用。