分配给基类的静态只读字段

发布于 2024-08-04 21:01:23 字数 544 浏览 10 评论 0原文

public class ClassA
{
    public static readonly string processName;
} 

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

我在编译上述 C# 代码时遇到错误。

错误显示 - “无法分配静态只读字段(静态构造函数或变量初始值设定项除外)”,

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

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

上面的代码有什么错误? (如果有的话)我似乎找不到一个。错误消息没有帮助。因为按照它我没有做任何错事。

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

public class ClassA
{
    public static readonly string processName;
} 

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

I am getting an error while compiling the above C# code.

The error says -- "A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)"

But I am assigning it in a static constructor.

The need for such a static variable is that, the base class has methods that uses this variable, but the derived classes and the base class must have different values for this variable. But the value is constant across all instances of the respective class. It must be readonly because, it must not be changed by anywhere.

What is the error in the above code? (If there is any) I do not seem to be able to spot one. The error message is not helping. As I am not doing anything wrong according to it.

If there is an error, how can I implement this functionality? I know a simple workaround would be to make it an instance variable and assign them different values in the derived classes. But that is unnecessary as the value is constant across all the instances of the respective class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

路弥 2024-08-11 21:01:23

不过,您在错误静态构造函数中进行了分配。它只能在声明变量的类型的静态构造函数中分配。

假设您有另一个从 ClassC 派生的类,它执行相同的操作 - 您最终会覆盖该变量,该变量本来是只读的。无论您有多少个派生类,这里都有一个单个静态变量。

一种答案是避免使用静态变量,而是在基类中放置一个虚拟属性,并让每个派生类重写该属性以返回不同的常量:

public class ClassA
{
    public virtual string ProcessName { get { return "ClassAProcess"; } }
} 

public class ClassB : ClassA
{
    public override string ProcessName { get { return "MyProcess.exe"; } }
}

基本上选项将是将“静态”位分离到单独的层次结构中 - 实际上,听起来您想要类型而不是实例的多态性,而 .NET 中不支持这一点。

You're assigning in the wrong static constructor though. It can only be assigned in a static constructor for the type declaring the variable.

Suppose you have another class deriving from ClassC which does the same thing - you'd end up overwriting the variable, which is meant to be readonly. There's a single static variable here, however many derived classes you've got.

One answer is to avoid using a static variable but put a virtual property in the base class, and make each derived class override the property to return a different constant:

public class ClassA
{
    public virtual string ProcessName { get { return "ClassAProcess"; } }
} 

public class ClassB : ClassA
{
    public override string ProcessName { get { return "MyProcess.exe"; } }
}

Basically option would be to separate the "static" bits into a separate hierarchy - effectively it sounds like you want polymorphism over the type instead of instances, and that isn't supported in .NET.

梦里°也失望 2024-08-11 21:01:23

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

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

并使用 ProcessNames.Value 代替。显然,该值将通过这种方式公开获取。

但是,您应该查看在每个派生类中单独定义字段是否符合您的需要,如果不符合您的需要,则仅诉诸解决方法。

In your example, only a single field will exist, that of the base class and you can't have different values in a single field. Beside that, you can only initialize readonly fields in the same class, not in derived classes. A workaround could be defining a generic class like:

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

and use ProcessNames<DerivedClassType>.Value instead. Obviously, the value will be publicly accessible this way.

However, you should see if defining the field in each derived class separately fits your need and only resort to workarounds if it does not.

一江春梦 2024-08-11 21:01:23

给猫剥皮的方法有很多种。这是另一种方法。

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")
    {
    }
}

There's many ways to skin the cat. Here's another way you can do it.

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")
    {
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文