如果它们都存在,如何调用Foo(此对象o)而不是Foo(此T t)?

时间:2010-10-14 05:53:33

标签: c#

如何调用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);

    }
}

3 个答案:

答案 0 :(得分:9)

我不记得它在标准中的位置,但C#更喜欢调用最具体的重载。使用泛型,函数的泛型版本几乎总是优先考虑。因此,虽然intobject,但它更适合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)

由于iint,因此通用重载比采用object的更好匹配。如果您将i转换为object,则会调用非通用版本。

答案 2 :(得分:0)

显示方法是多余的。实际上你并不需要这两种方法。

首先让我解释为什么它总是执行Generic版本而不是另一个版本。

C#编译器将为方法调用找到最佳类型匹配。在所有调用中,泛型方法被证明是最佳匹配,因为泛型版本的类型参数将始终与调用中给出的相同。

所以对于Tools.Display(i),调用编译器会更喜欢通用版本,因为这是基于类型匹配的最佳选择。

即使在其他调用中,类型也是从参数中推断出来的,因此通用版本优先于另一个调用。