簡體   English   中英

覆蓋屬性的訪問者

[英]Overwriting a property's accessors

我馬上就跳進來。

假設AudioFile是一個抽象類,如下所示:

abstract class AudioFile 
{
    public string Title { get; set; }
}

現在,在大多數情況下,使用a.Title非常適合從AudioFile繼承的其他類。 但是,在MPEG文件的情況下,它存儲在id3變量中的不同對象中:

class MPEG : AudioFile 
{
    private ID3 id3;

    public new string Title {
        get {
            return id3.Title; 
        }
        set {
            id3.Title = value;
        }
    }
}

class WMA : AudioFile
{

}

我想要的是做以下事情:

AudioFile a;

if( isMPEG ) {
    a = LoadMPEG(); // Returns a new MPEG instance.
} else
if( isWMA ) {
    a = LoadWMA();  // Return a new WMA instance.
}

Console.WriteLine( a.Title );
// Other stuff with a.

我希望輸出是歌曲的標題,無論是MPEG還是WMA。 但是,當它的MPEG時,它不能按預期工作(因為它沒有使用id3對象)。 它的唯一工作方式是:

if( isMPEG ) {
    MPEG a = LoadMPEG();    // Returns a new MPEG instance.
    Console.WriteLine( a.Title );
    // Other stuff with a.
} else
if( isWMA ) {
    WMA a = LoadWMA();  // Return a new WMA instance.
    Console.WriteLine( a.Title );
    // Other stuff with a.
}

這不是我想要的。 關於如何做我想做的事情的想法?

使抽象類屬性為virtual以便派生類在需要不同行為時可以覆蓋它。

abstract class AudioFile
{
    public virtual string Title { get; set; } 
}

class MpegFile : AudioFile
{
    public override string Title { /* your custom getter and setter */ }
}

AudioFile file = new MpegFile();
string title = file.Title; // will use override

在您的版本中,您將抽象類屬性保留為非虛擬,並將派生類屬性標記為new 這允許您通過派生類的引用來使用自定義行為。 您失去了通過基礎體驗多態行為的能力。 new修飾符通過派生引用隱藏基本行為。 基本引用使用基本行為。

AudioFile file = new MPEG(); // will use base behavior for non-virtual methods
MPEG file = new MPEG(); // will use derived behavior when non-virtual methods are hidden by new

您可能碰巧來自Java背景。 在C#中,默認情況下成員不是虛擬的。 您必須將它們標記為virtual ,並使用override以多態方式替換或擴充基本實現。 (對於抽象類中的抽象成員,您可以使用關鍵字abstract而不是virtual 。)當基本方法不是虛擬的時, new關鍵字很有用,但您已經看到了它的局限性。

暫無
暫無

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

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