简体   繁体   English

覆盖属性的访问者

[英]Overwriting a property's accessors

I'll just jump right in. 我马上就跳进来。

Suppose AudioFile is an abstract class like so: 假设AudioFile是一个抽象类,如下所示:

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

Now, in most cases, using a.Title is perfectly suited for other classes that inherit from AudioFile. 现在,在大多数情况下,使用a.Title非常适合从AudioFile继承的其他类。 However, in the case of MPEG files, this is stored in a different object in the id3 variable: 但是,在MPEG文件的情况下,它存储在id3变量中的不同对象中:

class MPEG : AudioFile 
{
    private ID3 id3;

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

class WMA : AudioFile
{

}

What I would like is to do the following: 我想要的是做以下事情:

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.

I would expect the output to be, whether an MPEG or a WMA, the song's title. 我希望输出是歌曲的标题,无论是MPEG还是WMA。 However, when its MPEG, it doesn't work as expected (because it isn't using the id3 object). 但是,当它的MPEG时,它不能按预期工作(因为它没有使用id3对象)。 The only way it works is: 它的唯一工作方式是:

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.
}

Which is not what I want. 这不是我想要的。 And ideas on how to do what I want to do? 关于如何做我想做的事情的想法?

Make the abstract class property virtual so that derived classes can override it if they need different behaviors. 使抽象类属性为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

In your version, you leave the abstract class property non-virtual and mark the derived class property as new . 在您的版本中,您将抽象类属性保留为非虚拟,并将派生类属性标记为new This allows you to use your custom behavior only via the reference of the derived class. 这允许您通过派生类的引用来使用自定义行为。 You lose the ability to experience the polymorphic behavior via the base. 您失去了通过基础体验多态行为的能力。 The new modifier hides the base behavior only through the derived reference. new修饰符通过派生引用隐藏基本行为。 Base references use the base behavior. 基本引用使用基本行为。

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

You may happen to come from a Java background. 您可能碰巧来自Java背景。 In C#, members are not virtual by default. 在C#中,默认情况下成员不是虚拟的。 You must mark them as virtual , and use override to replace or augment the base implementations in a polymorphic way. 您必须将它们标记为virtual ,并使用override以多态方式替换或扩充基本实现。 (For abstract members in abstract classes, you would use the keyword abstract instead of virtual .) The new keyword is useful when the base method is not virtual, but you have already seen its limitation. (对于抽象类中的抽象成员,您可以使用关键字abstract而不是virtual 。)当基本方法不是虚拟的时, new关键字很有用,但您已经看到了它的局限性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM