假设我有类层次结构,当创建B的实例时,通过构造函数链将数字设置为默认值。由于_number的值应该是默认值,因此必须覆盖属性Number,以便删除set访问器。 / p>
abstract Class A
{
public int Number
{
get
{
return _number
}
set
{
_number = value;
}
}
}
Class B : Class A
{
public int Number
{
get
{
return _number
}
}
}
答案 0 :(得分:1)
这是不可能的,因为你想要并且有充分的理由。
你实际上打破了Liskov的替代原则。利斯科夫说
程序中的对象应该可以替换为它们的实例 子类型而不改变该程序的正确性
由于您的基类具有公共集,因此您的派生类也应如此。
我在Override Interface Method in another Interface中提出的几乎相同的论点都可以在这里应用
由于您可以传入需要基类的派生类,如果用户在属性上调用该集,会发生什么?
尽管新方法似乎是一种可能的解决方案,但实际上这是错误的,因为newing会隐藏基本属性并且不会覆盖它。它仍然可以访问,因为你没有隐藏设置部分(你只是隐藏了getter)。
如果您在基类中将setter设为私有,那么对于base或derived,setter将不会公开显示。但是,如果您正在使用构造函数赋值,则可以选择此选项。
答案 1 :(得分:0)
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
B b = new B(10);
// b.Number = 10; // Error here
}
}
public abstract class A
{
public A() { }
public A(int number)
{
Number = number;
}
private int _number;
public virtual int Number
{
get
{
return _number;
}
private set
{
_number = value;
}
}
}
public class B : A
{
public B(int number)
: base(number) { }
public override int Number
{
get
{
return base.Number;
}
}
}
}
答案 2 :(得分:-1)
可能类似
class B : A
{
public new int Number //NEW
{
get
{
return _number; //NUMBER IS DEFINED IN (A)
}
}
}
但这有问题。
即使这可以正常工作
B b = new B();
b.Number = 10; //COMPILER ERROR FOR READONLY PROPERTY
这将正确编译
A b = new B();
b.Number = 10; //NO ERROR