Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
281 views
in Technique[技术] by (71.8m points)

c# - What's the best way to ensure a base class's static constructor is called?

The documentation on static constructors in C# says:

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.

That last part (about when it is automatically called) threw me for a loop; until reading that part I thought that by simply accessing a class in any way, I could be sure that its base class's static constructor had been called. Testing and examining the documentation have revealed that this is not the case; it seems that the static constructor for a base class is not guaranteed to run until a member of that base class specifically is accessed.

Now, I guess in most cases when you're dealing with a derived class, you would construct an instance and this would constitute an instance of the base class being created, thus the static constructor would be called. But if I'm only dealing with static members of the derived class, what then?

To make this a bit more concrete, I thought that the code below would work:

abstract class TypeBase
{
    static TypeBase()
    {
        Type<int>.Name = "int";
        Type<long>.Name = "long";
        Type<double>.Name = "double";
    }
}

class Type<T> : TypeBase
{
    public static string Name { get; internal set; }
}

class Program
{
    Console.WriteLine(Type<int>.Name);
}

I assumed that accessing the Type<T> class would automatically invoke the static constructor for TypeBase; but this appears not to be the case. Type<int>.Name is null, and the code above outputs the empty string.

Aside from creating some dummy member (like a static Initialize() method that does nothing), is there a better way to ensure that a base type's static constructor will be called before any of its derived types is used?

If not, then... dummy member it is!

question from:https://stackoverflow.com/questions/4652454/whats-the-best-way-to-ensure-a-base-classs-static-constructor-is-called

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The rules here are very complex, and between CLR 2.0 and CLR 4.0 they actually changed in subtle and interesting ways, that IMO make most "clever" approaches brittle between CLR versions. An Initialize() method also might not do the job in CLR 4.0 if it doesn't touch the fields.

I would look for an alternative design, or perhaps use regular lazy initialization in your type (i.e. check a bit or a reference (against null) to see if it has been done).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...