确保调用基类的静态构造函数的最佳方法是什么? [英] What's the best way to ensure a base class's static constructor is called?

查看:32
本文介绍了确保调用基类的静态构造函数的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于 C# 中的静态构造函数的文档 说:

静态构造函数用于初始化任何静态数据,或执行需要的特定操作只执行一次.它被称为自动在第一个之前实例已创建或任何静态成员被引用.

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);
}

我假设访问 Type 类会自动调用 TypeBase 的静态构造函数;但情况似乎并非如此.Type.Namenull,上面的代码输出空字符串.

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.

除了创建一些虚拟成员(比如一个什么都不做的静态 Initialize() 方法),是否有更好的方法来确保基类型的静态构造函数在任何使用了它的派生类型?

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!

推荐答案

这里的规则 非常复杂,在 CLR 2.0 和 CLR 4.0 之间,它们实际上 以微妙而有趣的方式改变,IMO 使大多数聪明"的方法变得脆弱CLR 版本.如果 Initialize() 方法不涉及字段,则它可能无法在 CLR 4.0 中完成这项工作.

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.

我会寻找替代设计,或者可能在您的类型中使用常规延迟初始化(即检查一点或引用(针对 null)以查看它是否已经完成).

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).

这篇关于确保调用基类的静态构造函数的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆