2013-09-22 46 views
8

考慮以下代碼:呼叫在C#泛型方法

static void Main(string[] args) 
{ 
    Get<Student>(new Student()); 
    System.Console.Read(); 
} 

public static void Get<T>(T person) 
{ 
    Console.WriteLine("Generic function"); 
} 
public static void Get(Person person) 
{ 
    person.Show(); 
} 

這是我的Person類:

class Person 
{ 
    public void Show() 
    { 
     Console.WriteLine("I am person"); 
    } 
} 
class Student : Person 
{ 
    public new void Show() 
    { 
     Console.WriteLine("I am Student"); 
    } 
} 

我打電話Get並通過學生對method.Like這樣的:

Get<Student>(new Student()); 

所以我得到這個:Generic function。但是當我打電話Get像這樣:

Get(new Student()); 

我希望這個Get(Person person)被稱爲,但再次調用:Get<T>(T person)。 爲什麼編譯器有這種行爲?

+5

Look [here](http://stackoverflow.com/questions/3679562/generic-methods-and-method-overloading),問題基本相同 – Save

+5

過載優先的確切規則很複雜,並且在規範中:但我懷疑它實際上是調用'Get (Student)' - 這完全匹配; 'Get(Person)'不* *完全匹配,因爲您傳遞的是學生,而不是個人 –

回答

13

我可以參考Jon Skeet的書「C#深度」(現在的第二版),章節編號爲9.4.4。我改變了文字以適應你的情況。

選擇正確的重載方法

此時,編譯器考慮來自學生到 學生的轉化,從學生到人。從任何類型到 本身的轉換本身被定義爲比任何轉換爲​​不同的 類型更好,所以對於此特定調用,用T作爲學生方法的Get(T x)優於 Get(Person y)。

這本書裏有一個比較多的解釋,我至少強烈建議你仔細閱讀。