为继承的只读字段赋值?
所以我有一个有很多孩子的基类。该基类定义了一些具有默认值的只读属性和变量。这些可能会有所不同,具体取决于孩子。
只读属性/字段允许您更改构造函数内变量的值以及定义,但不能更改其他地方。如果我尝试更改子类构造函数中继承的只读变量的值,我会收到“只读变量只能在构造函数中分配”错误。这是为什么?在没有反射的情况下我该如何解决这个问题?
我的意图:允许用户通过脚本进行扩展,他们只能更改某些字段一次。
So I have a base class that has many children. This base class defines some readonly properties and variables that have default values. These can be different, depending on the child.
Readonly properties/fields allow you to change the value of the variable inside the constructor and also the definition, but nowhere else. I get a 'readonly variable can only be assigned to in a constructor' error if I try to change the value of an inherited readonly variable in the child class' constructor. Why is this and how can I work around this, without Reflection?
My intention: To allow user extensibility through scripts where they can only change certain fields once.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
原因是您只能分配给该类的构造函数中的只读字段。
根据readonly的定义在 C# 参考 中(强调我的):
要解决此问题,您可以在基类中创建一个受保护的构造函数,该构造函数采用只读属性的参数。
一个例子:
The reason is that you can only assign to readonly fields in the constructor of that class.
According to the definition of readonly in the C# Reference (emphasis mine):
To work around this, you could make a protected constructor in the base that takes a parameter for the readonly property.
An example:
您可以通过使用虚拟仅获取属性来获得您正在寻找的确切行为。
字段位于继承和重载模型之外,不应用于提供多态功能。
You could get the exact behavior you are looking for by using virtual get only properties.
Fields are out side the inheritance and overloading model and should not be used to provide polymorphic features.
亚当有正确的答案。如果您担心它将占用的空间(构造函数中的参数数量?),那么您应该使用不同的解决方案将其作为不同的问题来解决:创建一个 BaseConfig 类,其中包含所有这些属性,仅此而已然后,Base 可以从 BaseConfig 的属性分配所有只读字段,或者您可以让 Base 仅保留一个 BaseConfig 类型的只读字段,并引用该字段来获取值。
至于为什么会这样,请参阅 C# 构造函数执行顺序了解每个类的只读字段何时初始化/可初始化。
Adam has the right answer. If you're worried about the space it will take up (number of parameters in the constructor?) then you should address that as a different problem with a different solution: create a BaseConfig class, that contains all those properties and that is all that needs to be passed in. Base can then either assign all it's readonly fields from BaseConfig's properties, or you can instead have Base hold just one readonly field of type BaseConfig and refer to that for the values.
As to why this is, see C# constructor execution order regarding when each class's readonly fields would be initialized/initializable.
您可以将属性与 public get 访问器和 protected set 访问器一起使用。派生类可以设置此属性的值。
一个例子:
You can use property with public get accessor and protected set accessor. Derived classes can set value of this property.
An example:
这在设计上是不可能的。尝试将值传递给受保护的基类构造函数
this is impossible by design. try passing the values to a
protected
base class constructor这本质上就是 @rerun 的想法,但使用的是
abstract
而不是virtual
:This is essentially what @rerun came up with, but with
abstract
instead ofvirtual
: