在基类中我有这个属性:
public virtual string Text
{
get { return text; }
}
我想覆盖它并返回不同的文本,但我也希望能够设置文本,所以我这样做了:
public override string Text
{
get { return differentText; }
set { differentText = value; }
}
然而,这不起作用。我在set
下得到一个红色波浪形,说我无法覆盖,因为它没有设置访问器。为什么这是个问题?我该怎么办?
答案 0 :(得分:5)
public virtual string Text
{
get { return text; }
protected set {}
}
像这样改变基类属性,你试图覆盖不存在的set方法
答案 1 :(得分:5)
在第二个代码块中,您正在创建一个公共集方法,但声明中的“override”一词使编译器在基类中查找具有相同签名的方法。由于找不到该方法,因此无法创建您的设置。
正如ArsenMkrt所说,您可以将基本声明更改为包含受保护的集合。这将允许您覆盖它,但由于您仍然无法更改签名,因此您无法在子类中将此方法提升为public,因此您发布的代码仍然无效。
相反,您需要向基类添加一个公共虚拟集方法,该方法不执行任何操作(如果您尝试调用它,甚至会抛出异常),但这违背了类的用户所期望的如果你这样做的行为是这样的(我不会推荐它)确保它有很好的文档记录,用户不能错过它:
///<summary>
///Get the Text value of the object
///NOTE: Setting the value is not supported by this class but may be supported by child classes
///</summary>
public virtual string Text
{
get { return text; }
set { }
}
//using the class
BaseClass.Text = "Wibble";
if (BaseClass.Text == "Wibble")
{
//Won't get here (unless the default value is "Wibble")
}
否则将该set声明为子类中的单独方法:
public override string Text
{
get { return differentText; }
}
public void SetText(string value)
{
differentText = value;
}
答案 2 :(得分:3)
使用子类型时,您希望显示更多功能。这听起来像你不想覆盖,你想要阴影。只需使用new关键字隐藏可读/可写属性下的只读Text属性。
在基类中:
protected string text;
public string Text
{
get { return text; }
}
在派生类中:
new public string Text
{
get { return text; }
set { text = value; }
}
答案 3 :(得分:2)
这是一个问题,因为你打破了封装。你不能覆盖某些东西并使它更易于访问,这会把关于封装的一切都抛到窗外。
这是规则,它也适用于你的情况,尽管你实际上暴露了一些不是原始值的东西。
无法完全按照您的尝试行事。您必须在基类中创建一个setter,或者使用另一种设置新值的方法。
答案 4 :(得分:2)
您可以从基类隐藏属性:
public new string Text
{
get { return differentText; }
set { differentText = value; }
}
但在这种情况下,只有在通过此类型的变量操作对象时才使用该属性,而不是基类型