在链式构造函数中设置只读字段

时间:2014-10-06 01:43:06

标签: c#

我有一个类,它有两个只在构造函数中设置的只读字段。我有一个派生类,希望在构造函数中将这些值设置为不同的值;但是,尝试这样做会导致CS1091(无法将readonly字段分配给(构造函数或变量初始化程序除外)错误。

我不明白为什么会这样 - 我分配给构造函数中的字段。不是他们定义的班级之一。

是否存在一些我遗漏的微妙语法问题,或者这是不可能的?

(如果不可能的话,有很多方法 - 可能是没有setter的受保护的虚拟属性,以及私有的readonly支持字段;但从语法上来说它不会那么干净,所以我想避免它们,如果我能。)

public class BaseClass
{
    protected readonly ushort OffsetRoutine;
    protected readonly ushort OffsetString;

    public BaseClass()
    {
        this.OffsetRoutine = this.GetWord(Addresses.Header.OffsetRoutine);
        this.OffsetString = this.GetWord(Addresses.Header.OffsetString);
    }

    protected ushort GetWord(byte address)
    {
        // Chosen by fair dice roll on a d100.
        return 42;
    }
}

public class DerivedClass : BaseClass
{
    public DerivedClass()
        : base()
    {
        this.OffsetRoutine = 0;
        this.OffsetString = 0;
    }
}

3 个答案:

答案 0 :(得分:1)

其他答案没有提供关键细节 - 仅在声明或同一类的构造函数中设置readonly字段。这只是readonlyconst之间的差异之一。 const修饰符不允许您在构造函数中设置字段 - 仅在声明中。因此,不允许在派生类中设置readonly,因为该字段不在同一个类中。我假设您不需要变通方法,因为您似乎知道如何在必要时进行解决,并且还有其他答案在讨论这个问题。来自MSDN(http://msdn.microsoft.com/en-us/library/acdd6hb7.aspx):

  

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

仅举几例:

public class A
{
    protected const string constString = "Test";          //Allowed
    protected readonly string readonlyString = "Test";    //Allowed

    public A(){
      constString = "Test";      //Not allowed
      readonlyString = "Test";   //Allowed
    } 
}

public class B: A
{
    public B(){
      constString = "Test";      //Not allowed
      readonlyString = "Test";   //Not allowed
    }
}

答案 1 :(得分:0)

这是不可能的,我认为readonly这个词的含义足够清楚。

你的问题不明确,但你可能想要这样的事情:

private ushort _offsetRoutine;
private ushort _offsetString;

public BaseClass()
{
     _offsetRoutine= this.GetWord(Addresses.Header.OffsetRoutine);
     _offsetString= this.GetWord(Addresses.Header.OffsetString);
}

public ushort OffsetRoutine
{
    get { return _offsetRoutine;}
}

public ushort OffsetString
{
    get { return _offsetString;}
}

现在您可以访问OffsetRoutine OffsetString,但您无法更改其价值。

答案 2 :(得分:0)

将值发送到构造函数中。设置只读时无法调用方法。

这种方式有效。

    public class BaseClass
    {
        protected readonly ushort OffsetRoutine;
        protected readonly ushort OffsetString;

        public BaseClass(ushort value1, ushort value2)
        {
            OffsetRoutine = value1;
            OffsetString = value2;
        }
    }

    public class DerivedClass : BaseClass
    {
        public DerivedClass(ushort value1, ushort value2)
            : base(value1, value2)
        {

        }
    }