【发布时间】:2012-03-16 22:12:46
【问题描述】:
使用这种模式有什么好处或理由?..
public sealed class myStaticClass
{
private static bool _initialized;
private static object _lockObject;
private static string _someStaticField;
private static int _anotherStaticField;
private static string _nthStaticField;
static myStaticClass()
{
_initialized = false;
_lockObject = new object();
}
public myStaticClass()
{
}
public static void Initialize()
{
if(!_initialized)
{
lock(_lockObject)
{
if(!_initialized)
{
//do initializing
_someStaticField = someApplicationSetting;
_anotherStaticField = anotherApplicationSetting;
_nthStaticField = nthApplicationSetting;
_initialized = true;
}
}
}
}
public static string NthStaticField
{
get {
Initialize();
return _nthOtherField;
}
}
}
如果保证在访问任何类成员之前调用静态构造函数,并且只调用一次,那么为什么不将所有初始化逻辑放在静态构造函数中呢?
编辑:我已经更新了模式,以更好地反映我发现它的 .net 框架中的类。我已将类上的static 修饰符更改为sealed,并且还添加了一个空的public 构造函数。
ps。如果您想知道,我看到这种模式的类是 FormsAuthentication 类。
【问题讨论】:
-
查找 C# 的“双重检查锁定”和/或“延迟初始化”。有一篇很好的文章链接到几篇文章,讨论了获得这种惰性 [one-time-when-needed] 初始化的不同方法。 (而且发布的代码实际上不是在许多情况下推荐的方式之一;-)
-
啊,这里是来自 C# In Depth 的著名文章:csharpindepth.com/Articles/General/Singleton.aspx 列出了 5 种方法,并附有解释。
-
@pst 是对的,但应该更有力。 这段代码被严重破坏和错误。 你不能像这样安全地进行双重检查锁定!双重检查锁定的基本规则是你测试的东西必须是唯一你改变的东西。你不能使用一个标志来控制双重检查锁定,然后改变一些完全其他的变量;这决不能保证是安全的。如果您不完全了解运行时的内存模型,则不应尝试编写低锁代码。
-
在 pst 发布的第一个链接中阅读我的答案;这是著名的“危险地破坏错误实现的双重检查锁定模式”的又一个例子。
标签: c# static initialization