C#-无法在派生类构造函数中设置只读属性和字段

C#-无法在派生类构造函数中设置只读属性和字段,c#,constructor,derived-class,readonly-attribute,C#,Constructor,Derived Class,Readonly Attribute,我有如下的类结构 abstract class AMyAbstractClass { public readonly int MyReadonlyField; public int MyReadonlyProperty { get; }//read-only auto-property (syntactic sugar) } class MyConcreteClass : AMyAbstractClass { MyConcreteClass() { thi

我有如下的类结构

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无法分配给--它是只读的

分别

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



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

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

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) {
    }
}
关于
只读
字段。参考资料来源:

当一个领域 -声明包含一个只读修饰符,声明引入的字段是只读字段。直接指定为只读 字段只能作为该声明的一部分或在实例中出现 同一类中的构造函数或静态构造函数

以及来自c#6的描述:

。。。只能在文件的正文中设置属性 建造商:

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) {
    }
}

第一条错误消息可能有点不清楚,但您只需要在基类中使用构造函数(可能也需要受保护的构造函数)。这是我在Visual Studio 2017中获得的逐字错误消息。在这两种情况下,抽象类是否有任何构造函数都是一样的。我要添加这一点(除非您使用Unity)您应该真正避免使用公共变量(即使是只读的)。使用您的属性访问变量请尝试回答我问题中的“为什么”部分。@Elaskanator,我已经引用了您的ECMA规范文章中的措辞“…在同一类中”,这似乎确实是这样。我还是不明白为什么。MSDN关于自动属性的文章甚至没有指出限制。另外,我记不起它叫什么了,谢谢你们挖掘了“只读自动属性”链接。@Elaskanator,所以
为什么只在同一类型的构造函数中
-这对我来说很有意义,我认为这是因为封装,两种情况下的只读性质意味着外部代码可能不会改变它们,在这里,甚至子类型构造函数也是外部代码