C# 作为子类构造函数目标的只读字段
当您有一个在对象安装时已知的变量(以后不应更改)时,应使用只读字段 但是,不允许从子类的构造函数中分配只读字段。 如果超类是抽象的,这甚至不起作用 有没有人能很好地解释为什么这不是一个好主意,或者在C#language中缺乏C# 作为子类构造函数目标的只读字段,c#,inheritance,variable-assignment,readonly,restriction,C#,Inheritance,Variable Assignment,Readonly,Restriction,当您有一个在对象安装时已知的变量(以后不应更改)时,应使用只读字段 但是,不允许从子类的构造函数中分配只读字段。 如果超类是抽象的,这甚至不起作用 有没有人能很好地解释为什么这不是一个好主意,或者在C#language中缺乏 abstract class Super { protected readonly int Field; } class Sub : Super { public Sub() { this.Field = 5; //Not com
abstract class Super
{
protected readonly int Field;
}
class Sub : Super
{
public Sub()
{
this.Field = 5; //Not compileable
}
}
PS:通过在超类中的受保护构造函数中指定只读字段,当然可以达到相同的结果。我能看到的唯一原因是因为“它就是这样设计的”,如下所示: 对只读字段的直接赋值只能作为其一部分进行 中的实例构造函数或静态构造函数中的 同一班 只读的意义在于它不能更改,如果派生类可以修改,那么这将不再是真的,并且将违反封装(通过修改另一个类的内部结构)
你可以试试这样的 我想主要原因是所有.NET语言实现都增加了复杂性 此外,还有一个简单的解决方法:
abstract class Super
{
protected readonly int Field;
protected Super(int field)
{
this.Field = field;
}
}
class Sub : Super {
public Sub():base(5)
{
}
}我会用C#中的抽象/虚拟属性来建模 在我看来,这是一个比使用包含每个只读字段作为参数的构造函数更好的解决方案。一方面是因为编译器也能够内联此函数,另一方面是因为构造函数解决方案在派生类中看起来像这样:
class Sub : Super {
public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}
如果您已经有了一个接受单个int值的构造函数,那么这也可能不起作用。我更喜欢在超类中使用受保护的构造函数(正如alexm所提到的),并带有xml注释。
这将消除DonAndre在代码注释中所说的问题。没错。但是它仍然不适合抽象类吗?也许是因为可能有多个子类。这可能是不合适的,也许我们永远也不知道设计决策的确切原因。我不明白为什么它不适合抽象类,因为它们可以有构造函数,因此只读字段可以工作。是的,我在问题中提到过:)还有,alexm在大约10分钟前发布了完全相同的答案。这不是编辑,但无论如何!这是一个巧妙的解决办法,正是我所寻求的解决方案。这只是吹毛求疵,但为了增强可读性,我会做一个小小的修改(不是一个字):在子类中声明一个变量“private readonly Int32 CONCRETE_FIELD=5”。然后对于构造函数“public Son():base(CONCRETE_FIELD){}。此外,编译器错误不准确:
error 68无法为只读字段赋值(构造函数或变量初始值设定项中除外)
abstract class Super {
protected abstract int Field { get; }
}
class Sub : Super {
protected override int Field { get { return 5; } }
}
class Sub : Super {
public Sub() : base(5) { } // 5 what ?? -> need to check definition of super class constructor
}