使用静态构造函数的单例实现惰性
Singleton implementation laziness with static constructor
Jon Skeet 建议 in his singleton implementation that if you require the maximum laziness for your singleton 你应该添加一个静态构造函数,这将使编译器将类型标记为 beforefieldinit。
但是,我做了一些测试,它似乎更懒没有 beforefieldinit。
代码示例(私有构造函数调用输出到控制台并验证字段是否已初始化:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public static string Stub()
{
return "123";
}
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
//static Singleton()
//{
//}
private Singleton()
{
Console.WriteLine("private ctor");
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
当我调用 Singleton.Stub() 时,私有构造函数没有被命中,当我取消注释静态构造函数时,私有构造函数总是被调用。
这是我能追踪到的由静态构造函数造成的唯一区别。
在我试图理解 beforefieldinit 有什么区别的过程中,我也阅读了 Skeet 的回答 in this post 尝试将 false 传递给 DoSomething() - 无论有没有静态构造函数,私有构造函数都没有打电话。
public static void DoSomething(bool which)
{
if (which)
{
var a = Singleton.Stub();
}
else
{
Faketon.Stub();
}
}
When I call Singleton.Stub() the private constructor is not being hit, when I uncomment the static ctor private constuctor is always called.
不清楚这里 which
的值是什么,但基本上你有四种情况:
- 静态构造函数,
Singleton.Stub
已调用:类型初始值设定项保证 运行
- 静态构造函数,
Singleton.Stub
未调用:类型初始化程序保证不会 运行
- 没有静态构造函数,
Singleton.Stub
调用:类型初始值设定项可能 运行,但不保证
- 没有静态构造函数,
Singleton.Stub
未被调用:类型初始值设定项可能 运行,但不保证
最后两种情况的区别仅在于,如果将 Singleton.Stub
更改为使用静态字段,则第三种情况变为 "type initializer is guaranteed to run"。
Jon Skeet 建议 in his singleton implementation that if you require the maximum laziness for your singleton 你应该添加一个静态构造函数,这将使编译器将类型标记为 beforefieldinit。
但是,我做了一些测试,它似乎更懒没有 beforefieldinit。
代码示例(私有构造函数调用输出到控制台并验证字段是否已初始化:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
public static string Stub()
{
return "123";
}
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
//static Singleton()
//{
//}
private Singleton()
{
Console.WriteLine("private ctor");
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
当我调用 Singleton.Stub() 时,私有构造函数没有被命中,当我取消注释静态构造函数时,私有构造函数总是被调用。
这是我能追踪到的由静态构造函数造成的唯一区别。
在我试图理解 beforefieldinit 有什么区别的过程中,我也阅读了 Skeet 的回答 in this post 尝试将 false 传递给 DoSomething() - 无论有没有静态构造函数,私有构造函数都没有打电话。
public static void DoSomething(bool which)
{
if (which)
{
var a = Singleton.Stub();
}
else
{
Faketon.Stub();
}
}
When I call Singleton.Stub() the private constructor is not being hit, when I uncomment the static ctor private constuctor is always called.
不清楚这里 which
的值是什么,但基本上你有四种情况:
- 静态构造函数,
Singleton.Stub
已调用:类型初始值设定项保证 运行 - 静态构造函数,
Singleton.Stub
未调用:类型初始化程序保证不会 运行 - 没有静态构造函数,
Singleton.Stub
调用:类型初始值设定项可能 运行,但不保证 - 没有静态构造函数,
Singleton.Stub
未被调用:类型初始值设定项可能 运行,但不保证
最后两种情况的区别仅在于,如果将 Singleton.Stub
更改为使用静态字段,则第三种情况变为 "type initializer is guaranteed to run"。