2011-02-09 47 views
3

考慮以下(LinqPad)示例。類X中的ToString標記爲虛擬。爲什麼這裏的輸出不等於「嗨,我是Y,你好,我是X」,而是打印了typename?當然,標記ToString虛擬是錯誤的,因爲它在Object中被定義爲虛擬,我只是試圖理解這裏發生的事情。在基類中標記ToString虛擬,會發生什麼?

void Main() 
{ 
    Y y = new Y(); 
    Console.WriteLine(y); 
} 

// Define other methods and classes here 

class X 
{ 
    public virtual String ToString() 
    { 
    return "Hi, I'm X"; 
    } 
} 

class Y : X 
{ 
    public override String ToString() 
    { 
    return "Hi, I'm Y, " + base.ToString(); 
    } 
} 
+1

這是一個關於虛擬和非虛擬方法的很棒的演示:http://msdn.microsoft.com/en-us/library/aa645767%28v=vs.71%29.aspx – 2011-02-09 18:43:08

回答

15

這是在創造一個X虛擬方法稱爲ToString()其中隱藏Object.ToString()。所以,如果您有:

Y y = new Y(); 
X x = y; 
Object o = y; 

Console.WriteLine(y.ToString()); // Shows "Hi, I'm Y, Hi, I'm X"; 
Console.WriteLine(x.ToString()); // Shows "Hi, I'm Y, Hi, I'm X"; 
Console.WriteLine(o.ToString()); // Calls object.ToString; shows just "Y" 

調用只是

Console.WriteLine(y); 

相當於線下決賽,這就是爲什麼在打印類型名稱。

基本上,你的X.ToString方法應該覆蓋object.ToString()方法:

public override String ToString() 
{ 
    return "Hi, I'm X"; 
} 
+0

好吧,讓完美感。 – 2011-02-09 22:48:31

8

通過使用virtual String ToString()class X,你是 「隱藏」 的,而不是object.ToString覆蓋它。

當您撥打Console.WriteLine(y);時,它會呼叫object.ToString()。既然你沒有覆蓋這個,你的方法永遠不會被調用。

這就是說,編譯器將發出警告:

警告1 'X.ToString()' 揣繼承的成員 'object.ToString()'。要使當前成員重寫該實現,請添加override關鍵字。否則,添加新的關鍵字。

+0

LinqPad沒有警告...希望他們在那裏;)。 – 2011-02-09 22:48:53

相關問題