[英]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.