2010-10-14 23 views
1

如何調用擴展對象類的Display方法?如果它們都存在,如何調用Foo(this對象)而不是Foo(this T t)?

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); 

    } 
} 

回答

9

我不記得在哪裏標準,它說,但C#喜歡叫最具體超載。隨着泛型,函數的通用版本幾乎總是優先考慮。因此,intobject,因爲通用(Display<int>(int))的實現完全匹配,所以它更適合Display<T>(T)而不是Display(object)。添加一個事實,即C#可以單獨計算出T中的哪一類型,並且您可以看到您遇到的行爲。

所以,你必須明確地轉換爲一個對象調用該對象的版本:

((object)i).Display(); 

或者:

Tools.Display((object)i); 

而且你將有一個奇怪的(但明智的)問題如果你這樣做:

object o = 5; 
o.Display(); 
o.Display<object>(); 

這將在第一種情況下調用object版本,在第二種情況下調用通用版本。有趣的時間與參數!

+1

+1用於指定兩種方式,因爲OP聲明它是擴展方法。 – BoltClock 2010-10-14 05:57:59

1

由於iint,通用超載比採用object的更好匹配。如果您將i轉換爲object,則將調用非通用版本。

0

顯示方法是多餘的。你實際上不需要兩種方法在一起。

首先讓我解釋爲什麼它總是執行通用版本而不是其他版本。

C#編譯器會爲方法調用找到最好的類型匹配。在所有調用中,泛型方法都是最好的匹配,因爲泛型版本的類型參數總是與調用中給出的相同。

因此對於Tools.Display(i)調用編譯器將更喜歡通用版本,因爲這是基於類型匹配的最佳選項。

即使在其他調用中,類型也是從參數中推斷出來的,因此通用版本最好稱爲另一種調用。

相關問題