如何调用Display方法扩展对象类?
static class Tools
{
public static void Display<T>(this T t)
{
Console.WriteLine("generic: " + t.GetType());
}
public static void Display(this object o)
{
Console.WriteLine("object: " + o.GetType());
}
}
class Program
{
static void Main(string[] args)
{
int i = 100;
// all will invoke the generic version.
Tools.Display<int>(i);
i.Display();
Tools.Display(i);
}
}
答案 0 :(得分:9)
我不记得它在标准中的位置,但C#更喜欢调用最具体的重载。使用泛型,函数的泛型版本几乎总是优先考虑。因此,虽然int
是object
,但它更适合Display<T>(T)
而不是Display(object)
,因为通用(Display<int>(int)
)的实现完全匹配。添加一个事实,即C#可以自己确定T
中属于哪种类型,并且您会看到您遇到的行为。
因此,您必须显式转换为对象以调用对象版本:
((object)i).Display();
可替换地:
Tools.Display((object)i);
如果你这样做,你会有一个好奇(但明智的)问题:
object o = 5;
o.Display();
o.Display<object>();
这将在第一种情况下调用object
版本,在第二种情况下调用通用版本。有趣的时间与参数!
答案 1 :(得分:1)
由于i
是int
,因此通用重载比采用object
的更好匹配。如果您将i
转换为object
,则会调用非通用版本。
答案 2 :(得分:0)
显示方法是多余的。实际上你并不需要这两种方法。
首先让我解释为什么它总是执行Generic版本而不是另一个版本。
C#编译器将为方法调用找到最佳类型匹配。在所有调用中,泛型方法被证明是最佳匹配,因为泛型版本的类型参数将始终与调用中给出的相同。
所以对于Tools.Display(i),调用编译器会更喜欢通用版本,因为这是基于类型匹配的最佳选择。
即使在其他调用中,类型也是从参数中推断出来的,因此通用版本优先于另一个调用。