2008-12-23 67 views
4

我有一個帶有虛擬方法的基類以及覆蓋該方法的多個子類。C#調用被重寫的子類方法,但不知道它是子類實例

當我遇到這些子類之一時,我想調用重寫的方法,但不知道子類。我可以想到醜陋的方法來做到這一點(檢查一個值並進行轉換),但似乎應該有一種用語言來表達的方式。我希望List在同一個列表中包含多個子類,否則顯然我只能創建一個List。

編輯:修正了,這是錯誤的代碼,導致非常合適的第一個答案我:)

例如評論,:

Class Foo 
{ 
    public virtual printMe() 
    { 
     Console.Writeline("FOO"); 
    } 
} 

Class Bar : Foo 
{ 
    public override printMe() 
    { 
     Console.Writeline("BAR"); 
    } 
} 

List<Foo> list = new List<Foo>(); 
// then populate this list with various 'Bar' and other overriden Foos 

foreach (Foo foo in list) 
{ 
    foo.printMe(); // prints FOO.. Would like it to print BAR 
} 
+0

如何打印Foo,如果它是派生類重寫虛擬方法?在你的代碼示例中錯字? – mmcrae 2015-06-24 15:48:41

回答

8
class Foo 
{ 
    public virtual void virtualPrintMe() 
    { 
     nonVirtualPrintMe(); 
    } 

    public void nonVirtualPrintMe() 
    { 
     Console.Writeline("FOO"); 
    } 
} 

class Bar : Foo 
{ 
    public override void virtualPrintMe() 
    { 
     Console.Writeline("BAR"); 
    } 
} 

List<Foo> list = new List<Foo>(); 
// then populate this list with various 'Bar' and other overriden Foos 

foreach (Foo foo in list) 
{ 
    foo.virtualPrintMe(); // prints BAR or FOO 
    foo.nonVirtualPrintMe(); // always prints FOO 
} 
+0

這是我想要的行爲,但沒有得到..我的問題竟然是加載舊的基類類型的舊序列化對象,而不是新的子類。 – 2008-12-23 23:28:47

1

爲什麼它應打印「富」?這不是虛擬方法的目的。整個觀點是派生類可以在不改變接口的情況下改變函數的工作方式。 Foo對象將打印「Foo」,而Bar對象將打印「Bar」。還有其他什麼是錯的。

+0

你是對的。我原本發佈的代碼段中的評論中存在一個錯誤。它調用基類方法,大概是因爲它不知道它是一個子類實例。 – 2008-12-23 23:22:28

0

使用新的修飾符可以顯式隱藏從基類繼承的成員。要隱藏繼承的成員,請使用相同名稱在派生類中聲明它,然後使用新修飾符對其進行修改。這將導致你想要的行爲。

欲瞭解更多信息請點擊這裏:http://geekswithblogs.net/Mohamed/articles/28613.aspx

0

爲了獲得在這種情況下,你想要的行爲,你可以刪除該虛擬基類和子類使用新的。

但是,就像埃德斯旺格表示,你爲什麼?

0

是不是有一個解決方案,你只投你要調用另一個對象:

foo.printMe(); // prints FOO.. Would like it to print BAR 

成爲

(Foo)foo.printMe(); // foo can be any derived class of Foo. 

還是我失去了這個問題的某些部分?

+1

第二個會調用printMe並嘗試將返回值轉換爲(Foo)。它返回無效。 – 2008-12-24 00:00:00

相關問題