5

我有一个如下的类结构

abstract class AMyAbstractClass {
    public readonly int MyReadonlyField;
    public int MyReadonlyProperty { get; }//read-only auto-property (syntactic sugar)
}
class MyConcreteClass : AMyAbstractClass {
    MyConcreteClass() {
        this.MyReadonlyField = 1;
        this.MyReadonlyProperty = 1;
    }
}

这会引发编译错误

不能分配只读字段(在构造函数或变量初始化程序中除外)

无法将属性或索引器“AMyAbstractClass.MyReadonlyProperty”分配给 - 它是只读的

分别。

在第一种情况下,错误消息是错误的,因为它在构造函数中设置的!


我可以想出具有不可变对象属性的替代方法,但为什么不允许这种情况?这种封装有哪些好的做法?

4

1 回答 1

7

您需要通过基类的构造函数传播它们:

abstract class AMyAbstractClass {
    public readonly int MyReadonlyField;
    public int MyReadonlyProperty { get; }//syntactic sugar
    protected AMyAbstractClass (int fieldValue, int propertyValue) {
        this.MyReadonlyField = fieldValue;
        this.MyReadonlyProperty = propertyValue;
    }
}
class MyConcreteClass : AMyAbstractClass {
    public MyConcreteClass() 
        : base(fieldValue: 1, propertyValue:1) {
    }
}

关于readonly领域。来自ECMA-334 C# 语言规范的参考,第 15.5.3 章

当 field-declaration 包含 readonly 修饰符时,声明引入的字段是 readonly fields 。对只读字段的直接赋值只能作为该声明的一部分或在同一类的实例构造函数或静态构造函数中发生。

以及来自 c# 6的只读自动属性的描述:

...属性只能在构造函数的主体中设置:

于 2019-08-05T15:57:47.957 回答