none
Singleton 延迟初始化 RRS feed

  • 问题

  • public sealed class Singleton {
    	// 这实现了延迟初始化,并具有很多优势,当然也存在一些缺点。
    	// 详细内容请访问:《Implementing the Singleton Pattern in C#》。
    	// 文章包含五种Singleton实现,就模式、线程、效率、延迟初始化等很多方面进行了详细论述。
    	private Singleton() { }
    
    	public static Singleton Instance {
    		get { return Nested.instance; }
    	}
    
    	/// <summary>
    	/// 嵌套的类,辅助创建单一实例
    	/// </summary>
    	public class Nested {
    		internal static readonly Singleton instance = new Singleton();
    
    		// Explicit static constructor to tell C# compiler not to mark type as beforefieldinit
    		// 静态构造函数,明确的告诉C#编译器不必将类型声明为 readonly    
    		static Nested() { }
    	}
    }
    


    我不知道这样有什么好处? 能否举例说明下?

    我去Google 百度 找了都没有详细的说明这个实现的优缺点.

    2011年6月19日 20:41

答案

  • 主要是那个 beforefieldinit,那个指示器是 IL,它的作用是指示该成员在所有字段初始化前被初始化,在 C# 中的等同效果就是 readonly。

    强制声明一个 static 的构造函数,IL 会把 readonly 的那个 instance 字段初始化代码放到静态构造函数中去,而不是用 beforefieldinit,这样,当第一次访问 Singleton.Instance 时,instance 才会被初始化,而不是在 CLR 启动并加载含有 Nested 类型后。

    我强烈建议不要使用这种方式。因为这种 Singleton 实现方式使用了对 C# 编译器优化的一个 Trick,但我们不能保证今后的 C# 编译器会产生相同效果的代码。任何对于编译器优化的依赖都不应该被用到生产环境中,这就好比 C# 中的 __arglist 等隐藏关键字。


    Mark Zhou
    • 已标记为答案 钱仔 2011年6月24日 13:27
    2011年6月20日 6:41
  • 您好 钱仔,

    从代码上看那个类是密封的,肯定是不允许继承的。就算你继承了,子类中也是不包含父类的信息的。

    还有,这有一个关与注释里提到的5Singleton的实现的文章:

                    单件模式在C#中的实现--Implementing the Singleton Pattern in C#

    希望能对你有用。


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 钱仔 2011年6月24日 13:27
    2011年6月22日 7:23
    版主

全部回复

  • 主要是那个 beforefieldinit,那个指示器是 IL,它的作用是指示该成员在所有字段初始化前被初始化,在 C# 中的等同效果就是 readonly。

    强制声明一个 static 的构造函数,IL 会把 readonly 的那个 instance 字段初始化代码放到静态构造函数中去,而不是用 beforefieldinit,这样,当第一次访问 Singleton.Instance 时,instance 才会被初始化,而不是在 CLR 启动并加载含有 Nested 类型后。

    我强烈建议不要使用这种方式。因为这种 Singleton 实现方式使用了对 C# 编译器优化的一个 Trick,但我们不能保证今后的 C# 编译器会产生相同效果的代码。任何对于编译器优化的依赖都不应该被用到生产环境中,这就好比 C# 中的 __arglist 等隐藏关键字。


    Mark Zhou
    • 已标记为答案 钱仔 2011年6月24日 13:27
    2011年6月20日 6:41
  • 延迟初始化 是否支持继承..如果是的话应该如何实现?
    2011年6月21日 9:02
  • 您好 钱仔,

    从代码上看那个类是密封的,肯定是不允许继承的。就算你继承了,子类中也是不包含父类的信息的。

    还有,这有一个关与注释里提到的5Singleton的实现的文章:

                    单件模式在C#中的实现--Implementing the Singleton Pattern in C#

    希望能对你有用。


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 钱仔 2011年6月24日 13:27
    2011年6月22日 7:23
    版主
  • 谢谢

    2011年6月24日 13:27