Assigning to static readonly field of base class

Poulo picture Poulo · Sep 14, 2009 · Viewed 7k times · Source
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.

Answer

Jon Skeet picture Jon Skeet · Sep 14, 2009

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.