泛型单一模式

本文介绍了使用泛型实现单例模式的方法,并通过一个具体的示例进行了解释。该实现利用了嵌套类的静态构造函数来达到完全延迟初始化的目的,并使用反射确保私有构造函数的正确调用。

泛型单一模式类:(fully lazy instantiation) 

public   sealed   class  Singleton < T >
        
where  T :  class
    {
        
        
public   static  T Instance
        {
            
get
            {
                
return  Nested.instance;
            }
        }

        
private   class  Nested
        {
            
//  Explicit static constructor to tell C# compiler
            
//  not to mark type as beforefieldinit
             static  Nested()
            {
            }

            
internal   static   readonly  T instance  =   typeof (T).InvokeMember( typeof (T).Name, BindingFlags.CreateInstance  |  BindingFlags.Instance  |  BindingFlags.NonPublic,  null null null as  T;
        }
    }

实现要点
1. 静态构造函数
静态构造函数用于初始化任何静态数据,所以它的执行顺序应该在静态成员初始化之后。

class  Test
    {
        
static   int  value =   1 // 第一步

        
static   string  staticString;

        
static  Test()
        {
// 第三步
            value  =   2 ;
            value2
=   3 ;
        }

        
public   static   int  value2 =   1 // 第二步

    }

当程序第一次执行如下语句时
Test test
=   new  Test();
执行顺序就是上面标出的步骤。
也就是说 
test.value 
=   2
test.value2 
=   3

2. 嵌套类的静态构造函数的作用
嵌套类的静态构造函数不会随着外部类的触发而初始化。有了嵌套类的静态构造函数,它会告诉C#编译器只有当需要使用内嵌类的时候,嵌套类的静态数据才开始初始化。所以上面介绍的单一模式是属于完全延迟初始化。
3.利用反射时使用"BidingFlags.NonPublic”,确保调用的的具体单一实例类中的private constructor.事实上,具体单一实例类中不应该有public的构造函数。为了就是确保不被误实例化。
4.使用sealed 关键字,防止被继承。

具体单一实例类: 

ContractedBlock.gif ExpandedBlockStart.gif Code
/// <summary>
    
/// SingleInstanceClass is a Singleton.
    
/// </summary>
    public class SingleInstanceClass
    {
        
#region Constructors

        
/// <summary>
        
/// Private constructor to prevent casual instantiation of this class.
        
/// </summary>
        private SingleInstanceClass() 
        {
            
// Show that the constructor is called.
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(
"SingleInstanceClass created.");
            Console.ResetColor();

            
// Increment instance counter.
            _count++;
        }

        
#endregion Constructors


        
#region Properties

        
/// <summary>
        
/// Gets the single instance of SingleInstanceClass.
        
/// </summary>
        public static SingleInstanceClass Instance 
        { 
            
get { return Singleton<SingleInstanceClass>.Instance; } 
        }

        
/// <summary>
        
/// Gets the number of SingleInstanceClass instances that have been created.
        
/// </summary>
        public static int Count { get { return _count; } }

        
#endregion Properties



        
#region Methods

        
/// <summary>
        
/// Simulates a static call.
        
/// </summary>
        public static void DoStatic() { Console.WriteLine("DoStatic() called."); }

        
/// <summary>
        
/// Simulates an instance call.
        
/// </summary>
        public void DoInstance() { Console.WriteLine("DoInstance() called."); }

        
#endregion Methods


        
#region Members

        
/// <summary>
        
/// Instance counter.
        
/// </summary>
        private static int _count = 0;

        
#endregion Members
    }

 Main:

ContractedBlock.gif ExpandedBlockStart.gif Code
ExpandedBlockStart.gifContractedBlock.gif/**//// <summary>
    
/// Singleton demo program.
    
/// </summary>

    class Program
ExpandedBlockStart.gifContractedBlock.gif    
{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Entry point.
        
/// </summary>

        static void Main()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{            

            
// Show that initially the count is 0; calls a static property which doesn't create the Singleton.
            Console.WriteLine("---");
            Console.WriteLine(
"Initial instance count: {0}", SingleInstanceClass.Count);

            
// Similar to above; show explicitly that calling a static methods doesn't create the Singleton.
            Console.WriteLine("---");
            Console.WriteLine(
"Calling DoStatic()");
            SingleInstanceClass.DoStatic();
            Console.WriteLine(
"Instance count after DoStatic(): {0}", SingleInstanceClass.Count);

            
// Show that getting the instance creates the Singleton.
            Console.WriteLine("---");
            Console.WriteLine(
"Calling DoInstance()");
            SingleInstanceClass.Instance.DoInstance();
            Console.WriteLine(
"Instance count after first DoInstance(): {0}", SingleInstanceClass.Count);

            
// Show that getting the instance again doesn't re-instantiate the class.
            Console.WriteLine("---");
            Console.WriteLine(
"Calling DoInstance()");
            SingleInstanceClass.Instance.DoInstance();
            Console.WriteLine(
"Instance count after second DoInstance(): {0}", SingleInstanceClass.Count);
            Console.ReadKey();



        }

    }

为什么不用double-check locking来实现,请参照

http://www.yoda.arachsys.com/csharp/singleton.html 

泛型单一模式参考地址:

http://www.codeproject.com/KB/architecture/GenericSingletonPattern.aspx

转载于:https://www.cnblogs.com/webfpc/archive/2009/04/22/1441221.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值