我有一个类,它有两个只在构造函数中设置的只读字段。我有一个派生类,希望在构造函数中将这些值设置为不同的值;但是,尝试这样做会导致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;
}
}
答案 0 :(得分:1)
其他答案没有提供关键细节 - 仅在声明或同一类的构造函数中设置readonly
字段。这只是readonly
和const
之间的差异之一。 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)
{
}
}