9
public class ClassA
{
    public static readonly string processName;
} 

public class ClassB : ClassA
{
    static ClassB()
    {
        processName = "MyProcess.exe";
    }
}

编译上述 C# 代码时出现错误。

错误说-“不能分配静态只读字段(静态构造函数或变量初始化程序除外)”

但我在静态构造函数中分配它。

对这样一个静态变量的需求是,基类有使用这个变量的方法,但是派生类和基类必须有这个变量的不同值。但是该值在相应类的所有实例中是恒定的。它必须是只读的,因为它不能被任何地方更改。

上述代码中的错误是什么?(如果有的话)我似乎无法找到一个。错误消息没有帮助。因为我没有做错任何事情。

如果有错误,我该如何实现这个功能?我知道一个简单的解决方法是使其成为实例变量并在派生类中为它们分配不同的值。但这是不必要的,因为该值在相应类的所有实例中都是恒定的。

4

3 回答 3

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 不支持这一点。

于 2009-09-14T10:56:42.340 回答
5

在您的示例中,将只存在一个字段,即基类的字段,并且您不能在单个字段中具有不同的值。除此之外,您只能readonly在同一个类中初始化字段,而不能在派生类中初始化。一种解决方法可能是定义一个泛型类,例如:

static class ProcessNames<T> {
   public static string Value { get; set; }
}

ProcessNames<DerivedClassType>.Value改用。显然,该值将以这种方式公开访问。

但是,您应该查看在每个派生类中分别定义字段是否符合您的需要,如果不符合则仅求助于变通方法。

于 2009-09-14T10:56:01.480 回答
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")
    {
    }
}
于 2009-09-14T11:04:01.140 回答