为继承的只读字段分配值?

Ste*_*nal 25 c# inheritance constructor readonly

所以我有一个有很多孩子的基类.此基类定义一些具有默认值的只读属性和变量.这些可能会有所不同,具体取决于孩子.

Readonly属性/字段允许您更改构造函数内部变量的值以及定义,但不能更改其他地方.如果我尝试在子类的构造函数中更改继承的只读变量的值,我会得到一个'readonly变量只能在构造函数中赋值'错误.为什么这样,如果没有反射,我该如何解决这个问题呢?

我的意图:允许用户通过脚本进行扩展,他们只能更改某些字段一次.

Ada*_*rth 25

原因是您只能分配给该类的构造函数中的只读字段.
根据C#Reference(强调我的)readonly的定义:

当字段声明包含只读修饰符时,声明引入的字段的赋值只能作为声明的一部分或在同一个类的构造函数中出现.

要解决此问题,您可以在基础中创建一个受保护的构造函数,该构造函数接受readonly属性的参数.

一个例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Base b = new Child();
            Console.WriteLine(b.i);
            Console.Read();
        }
    }

    class Base
    {
        public readonly int i;

        public Base()
        {
            i = 42;
        }

        protected Base(int newI)
        {
            i = newI;
        }
    }

    class Child : Base
    {
        public Child()
            : base(43)
        {}
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案的唯一缺点是它不允许您计算要传递给基类的值. (6认同)
  • @Kent:可以通过在基类构造函数的参数列表中调用静态方法.请参阅http://stackoverflow.com/questions/1651444/modifying-parameter-values-before-sending-to-base-constructor (3认同)

rer*_*run 8

您可以使用虚拟仅获取属性来获取您正在寻找的确切行为.

public class BSE
{
    virtual public int Prop 
    {
        get
        {
            return 6;
         }
     }
}
public class Derived : BSE
{
    public override int Prop
    {
         get
         {
             return 10;
         }
    }
 }
Run Code Online (Sandbox Code Playgroud)

字段在继承和重载模型之外,不应用于提供多态特征.


Tim*_*son 8

亚当有正确的答案.如果你担心它将占用的空间(构造函数中的参数数量?)那么你应该将其解决为另一个解决方案的另一个问题:创建一个包含所有这些属性的BaseConfig类,这就是全部需要传入.Base然后可以从BaseConfig的属性中分配它的所有只读字段,或者你可以让Base只保留一个BaseConfig类型的只读字段,并参考值.

至于为什么会这样,请参阅C#构造函数执行顺序,了解每个类的readonly字段何时初始化/可初始化.