簡體   English   中英

C# - 基類中的調用方法

[英]C# - Call Method in Base Class

我有2個班:

public class A
{
    public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

在我的代碼中,我執行以下操作:

B writeClass = new B();
writeClass.WriteLine("Output"); // I expect to see 'Output from B'
A otherClass = (A)writeClass;
otherClass.WriteLine("Output"); // I expect to see just 'Output'

我認為這會因多態性而起作用

但是,它總是每次寫入'B輸出'。 反正有沒有讓我按照我想要的方式工作?

編輯修復代碼示例。

當你使用NEW從基類“隱藏”一個方法時,你只是隱藏它,就是這樣。 當您明確調用基類實現時,它仍然會被調用。

不包含WriteLine,因此您需要修復它。 當我修好它時,我得到了

Output from B
Output


namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            B writeClass = new B(); 
            writeClass.WriteLine("Output"); // I expect to see 'Output from B' 
            A otherClass = (A)writeClass; 
            otherClass.WriteLine("Output"); // I expect to see just 'Output' 
            Console.ReadKey();
        }
    }

    public class A
    {
        public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
    }
    public class B : A
    {
        public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
    }
}

您在A類上的方法是Write,而不是WriteLine。 將其更改為相同的名稱,它將按預期工作。 我只是嘗試了並得到:

Output from B
Output

多態性(C#編程指南)很好地解釋了這一點。 (這是原始海報鏈接的較新版本。)該頁面顯示了派生類重寫虛擬成員以及新成員隱藏基類成員的示例。

對於新修飾符似乎存在一些混淆。 文檔

雖然您可以在不使用new修飾符的情況下隱藏成員,但結果是警告。 如果使用new來顯式隱藏成員,則會抑制此警告並記錄派生版本旨在替代的事實。

請注意,隱藏成員不需要是虛擬的。

最佳做法:

  • 非常喜歡覆蓋隱藏。 多態調用在OO語言中是慣用的。
  • 如果要隱藏成員,請始終使用new修飾符。
  • 永遠不要發布帶編譯器警告的代碼。
  • 如果團隊中的每個開發人員都同意無法修復編譯器警告,請禁用它。

覆蓋B類中的方法時,請勿使用new關鍵字。 並將A的方法聲明為virtual

'new'關鍵字使B的WriteLine實現覆蓋了A的實現。

不要接受這個作為答案,但根據我的經驗,以這種方式使用'new'關鍵字幾乎總是錯誤的。 它的可讀性和泥濘性都不那么清晰。

您的A類具有Write函數而不是WriteLine

public class A
{
    public virtual void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public override void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

第一:我想你想要將這些方法命名為“WriteLine”,但A類中的方法僅命名為“Write”。 第二個:是的,你從A繼承B但是對象仍然是“B”類型,所以現在我不認為你想要的是可能的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM