public sealed class Singleton
{
Singleton() {}
public static Singleton Instance
{
get
{
return Nested.instance;
}
}
class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested() {}
internal static readonly Singleton instance = new Singleton();
}
}
我希望在我当前的c#应用程序中实现Jon Skeet的单例模式。
我对代码有两个疑问
怎么可能访问嵌套类内部的外部类?我的意思是
内部静态只读Singleton实例= new Singleton();
这就是所谓的终结吗?
我无法理解这一评论
//显式的静态构造函数告诉c#编译器
//不将类型标记为beforefieldinit
这个评论告诉我们什么?
关于问题(1):Jon的答案是正确的,因为他隐式地将“Nested”类标记为私有,不使其为公共或内部:-)。你也可以通过添加'private'来明确地做到这一点:
private class Nested
关于问题(2):基本上关于beforeinitfield和类型初始化的帖子告诉你的是,如果你没有静态构造函数,运行时可以在任何时候初始化它(但在你使用它之前)。如果您确实有一个静态构造函数,那么静态构造函数中的代码可能会初始化字段,这意味着运行时只允许在您请求类型时初始化字段。
因此,如果你不想让运行时在你使用字段之前“主动”初始化它们,添加一个静态构造函数。
不管怎样,如果你正在实现单例,你要么希望它尽可能地延迟初始化,而不是当运行时认为它应该初始化你的变量时——或者你可能只是不在乎。从你的问题来看,我猜你希望他们越晚越好。
这就引出了Jon关于单身的帖子,在我看来,这是这个问题的潜在主题。哦,还有疑虑:-)
I'd like to point out that his singleton #3, which he marked 'wrong', is actually correct (because lock's automatically implies a memory barrier on exit). It also should be faster than singleton #2 when you use the instance more than once (which is more or less the point of a singleton :-) ). So, if you really need a lazy singleton implementation, I'd probably go for that one - for the simple reasons that (1) it's very clear for everyone that reads your code what is going on and (2) you know what will happen with exceptions.
如果你想知道:我永远不会使用单例#6,因为它很容易导致死锁和异常的意外行为。有关详细信息,请参见:lazy的锁定模式,特别是ExecutionAndPublication。