public class ClassA
{
public static readonly string processName;
}
public class ClassB : ClassA
{
static ClassB()
{
processName = "MyProcess.exe";
}
}
编译上面的C#代码时出错了。
错误说 - “无法分配静态只读字段(静态构造函数或变量初始化程序除外)”
但我在静态构造函数中分配它。
对这样的静态变量的需求是,基类具有使用此变量的方法,但派生类和基类必须具有此变量的不同值。但是,相应类的所有实例的值都是常量。它必须是只读的,因为它不能在任何地方改变。
上述代码中的错误是什么? (如果有的话)我似乎无法发现一个。错误消息没有帮助。因为我根据它没有做错任何事。
如果出现错误,我该如何实现此功能?我知道一个简单的解决方法是使它成为一个实例变量,并在派生类中为它们分配不同的值。但这是不必要的,因为值在各个类的所有实例中都是不变的。
答案 0 :(得分:15)
您正在错误的静态构造函数中进行分配。它只能在静态构造函数中为声明变量的类型分配。
假设您有另一个派生自ClassC的类,它执行相同的操作 - 您最终会覆盖该变量,这意味着只读。这里有一个单个静态变量,但是你有很多派生类。
一个答案是避免使用静态变量,但在基类中放置虚拟属性,并使每个派生类覆盖该属性以返回不同的常量:
public class ClassA
{
public virtual string ProcessName { get { return "ClassAProcess"; } }
}
public class ClassB : ClassA
{
public override string ProcessName { get { return "MyProcess.exe"; } }
}
基本上选项是将“静态”位分隔成一个单独的层次结构 - 实际上听起来你想要在类型而不是实例上使用多态,并且在.NET中不支持。
答案 1 :(得分:5)
在您的示例中,只存在一个字段,即基类的字段,并且您不能在单个字段中具有不同的值。除此之外,您只能在同一个类中初始化readonly
个字段,而不能在派生类中初始化。解决方法可能是定义一个通用类,如:
static class ProcessNames<T> {
public static string Value { get; set; }
}
并改为使用ProcessNames<DerivedClassType>.Value
。显然,价值将以这种方式公开获取。
但是,您应该看看在每个派生类中定义字段是否分别符合您的需要,如果没有,则仅采用解决方法。
答案 2 :(得分:1)
有很多方法可以给猫皮肤。这是你可以做到的另一种方式。
public class ClassA
{
public string ProcessName{ get; private set;}
public ClassA()
{
ProcessName = "ClassAProcess";
}
public ClassA(string processName)
{
ProcessName = processName;
}
}
public class ClassB : ClassA
{
public ClassB() : base("ClassAProcess")
{
}
}