2014-06-23 72 views
2

我已閱讀了一些關於C#中的方法隱藏和重寫的教程(包括MSDN網站上的教程),並在代碼片段I中遇到了問題寫在試圖理解其中的邏輯:瞭解C#中的虛方法,方法隱藏和重寫#

class A 
{ 
    public virtual void Foo() 
    { 
     Console.WriteLine("A"); 
    } 
} 

class B : A 
{ 
    public override void Foo() 
    { 
     Console.WriteLine("B"); 
    } 
} 

class C : B 
{ 
    new public virtual void Foo() 
    { 
     Console.WriteLine("C"); 
    } 
} 
class Driver 
{ 
    static void Main() 
    { 
     A a = new A(); 
     a.Foo(); 
     B b = new B(); 
     b.Foo(); 
     C c = new C(); 
     c.Foo(); 
     a = new B(); 
     a.Foo(); 
     a = new C(); 
     a.Foo(); 
     Console.ReadKey(); 
    } 
} 

每當我運行代碼,我得到這樣的輸出: 一個 乙 ç 乙 乙

我瞭解前四個,但不應該第五個輸出爲'C',因爲運行時實例是C而不是A?我不是很舒服,但隱藏方法,但不應該在類C中聲明「new public void void Foo()」允許調用Foo()而不是B中的那個?

+2

我不認爲你可以在同一時間使用'new'和'virtual'。 「虛擬」意味着你壓倒一切; '新'意味着你在遮掩。 –

+0

@RobertHarvey我也不這麼認爲;也許它只是給出警告?儘管對扎克來說,這基本上就是隱藏的。 –

+0

您已閱讀過有關方法重寫和隱藏的信息。最後一個案例是隱藏的。這不合理嗎? – usr

回答

3

第五個輸出是B,因爲您正在查看C實例,就好像它是A實例一樣,所以這就是您在方法調度開始的位置。

A.Foo它上升繼承鏈,檢查B.FooC.Foo。由於C.Foo標有new修飾符,因此實際調用B.Foo

你會得到C作爲輸出下面的代碼片段:

C c = new C(); 
c.Foo(); 
+0

第五個輸出不是C - 它是B,就像你在做'A instance = new C();' –

+0

@DanielMay當然,你是對的。只是一個錯字。 – MarcinJuraszek