当你有一个在object-instatiation中已知的变量时,应该使用readonly字段,之后不应该更改。
但是,不允许从子类的构造函数中分配只读字段。 如果超类是抽象的,这甚至都不起作用。
有没有人能够很好地解释为什么这不是一个好主意,或缺乏C#languange?
abstract class Super
{
protected readonly int Field;
}
class Sub : Super
{
public Sub()
{
this.Field = 5; //Not compileable
}
}
PS:您当然可以通过在超类中的受保护构造函数中分配只读字段来获得相同的结果。
答案 0 :(得分:12)
我能看到的唯一原因是因为“它只是按照这种方式设计的”,根据spec:
对只读字段的直接分配只能作为其中的一部分进行 声明或在实例中的构造函数或静态构造函数 同一个班级。
只读它的意思是它不能被改变,如果派生类可以修改那么这将不再是真的并且将违反封装(通过修改另一个类的内部)。
答案 1 :(得分:10)
public class Father
{
protected readonly Int32 field;
protected Father (Int32 field)
{
this.field = field;
}
}
public class Son : Father
{
public Son() : base(5)
{
}
}
您可以尝试这样的事情!
答案 2 :(得分:1)
我会用C#中的抽象/虚拟属性对此进行建模。
abstract class Super {
protected abstract int Field { get; }
}
class Sub : Super {
protected override int Field { get { return 5; } }
}
在我看来,这是一个比包含每个readonly字段作为参数的构造函数更好的解决方案。一个是因为编译器也可以内联这个,也因为构造函数解决方案在派生类中看起来像这样:
class Sub : Super {
public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}
如果您已经有一个采用单个int值的构造函数,那么这也可能不起作用。
答案 3 :(得分:0)
我认为主要原因是所有.NET语言实现的额外复杂性
另外,总有一个简单的解决方法:
abstract class Super
{
protected readonly int Field;
protected Super(int field)
{
this.Field = field;
}
}
class Sub : Super {
public Sub():base(5)
{
}
}
答案 4 :(得分:0)
我更喜欢在超类中使用受保护的构造函数(如alexm所述),并且可以使用xml注释。 这应该可以消除DonAndre在他的代码评论中所说的问题。