[英]Adding a setter to a virtual property in C#
我有这样的情况:
public abstract class BaseClass
{
public abstract string MyProp { get; }
}
现在,对于某些派生类,属性值是一个合成值,因此没有setter:
public class Derived1 : BaseClass
{
public override string MyProp { get { return "no backing store"; } }
}
这很好用。 但是,某些派生类需要更传统的后备存储。 但是,无论我如何编写它,如在自动属性上,或使用显式的后备存储,我都会收到错误:
public class Derived2 : BaseClass
{
public override string MyProp { get; private set;}
}
public class Derived3 : BaseClass
{
private string myProp;
public override string MyProp
{
get { return myProp;}
private set { myProp = value;}
}
}
Derived2.MyProp.set':无法覆盖,因为'BaseClass.MyProp'没有可覆盖的set访问器
我如何让它工作?
您可以做的最好的事情是将属性实现为virtual
而不是abstract
。 为基类中的每个抛出NotSupportedException
set
get
和set
块,并在派生类中相应地覆盖行为:
public virtual string MyProp {
get {
throw new NotSupportedException();
}
set {
throw new NotSupportedException();
}
}
基本上,你不能。 通过添加setter,您将更改属性的定义,因此它并不真正“覆盖”基本属性。 它就像你试图覆盖一个方法并向其添加另一个参数一样 - 它们将被视为不同的方法(重载)。 由于属性无法重载,因此无效。
您只需添加另一种方法来设置值(可能具有protected
可访问性)。
我建议避免使用虚拟或抽象属性。 相反,使用非虚拟属性链接到受保护的虚拟或抽象get / set方法。 这样做将允许派生类覆盖方法,并使用具有不同访问修饰符的属性来遮蔽属性。 由于基本属性本身是非虚拟的,因此永远不需要覆盖它,因此与新版本的命名冲突无关紧要。
布拉德利的建议很好,但是在我只有Setter应该是虚拟的情况下我做过的一件事就是这样做:
public class Root
{
private string _MyProp;
public string MyProp
{
get { return _MyProp;}
set { _MyProp = SetMyProp(value); }
}
protected virtual string SetMyProp(string suggestedValue)
{
return suggestedValue;
}
}
public class Child
: Root
{
protected override string SetMyProp(string suggestedValue)
{
string oReturn = base.SetMyProp(suggestedValue);
// Do some sort of cleanup here?
return oReturn;
}
}
它需要一些额外的工作,但它似乎保持更高程度的封装(例如,您可以防止子类覆盖Getter行为,并且您的子类不必知道属性背后的底层成员)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.