繁体   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