65.9K
CodeProject 正在变化。 阅读更多。
Home

通用单例设计模式

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.45/5 (6投票s)

2009 年 8 月 31 日

CPOL

1分钟阅读

viewsIcon

25377

downloadIcon

118

通用单例设计模式 C#

引言

本文描述了通用单例设计模式,它基于静态构造函数的行为。

背景

C# 中有两种类型的类构造函数:带或不带参数的“常规构造函数”和不带参数的“静态构造函数”。

常规构造函数
1. 如果类没有编写任何构造函数,C# 会提供一个隐式的默认构造函数,即一个没有参数的构造函数。
2. 构造函数可以重载
3. 构造函数按照继承顺序调用

静态构造函数
1. 静态构造函数是线程安全的
2. 类的静态构造函数在给定的应用程序域中最多执行一次
3. 静态字段初始值设定项的执行紧接在执行该静态构造函数之前发生
4. 静态构造函数按照继承的相反顺序调用

通用单例

通用单例设计模式基于“静态构造函数按照继承的相反顺序调用”和“类的静态构造函数最多执行一次”的原则。

/// <summary>
/// Singleton Template, OOD
/// </summary>
/// <typeparam name="T">class name</typeparam>
/// <example>
/// <code>
/// class MySingleton:Singleton<MySingleton>{}
/// </code>
/// </example>
public class Singleton<T> where T : class
{
         #region Ctor
         protected Singleton(){}
         #endregion
	#region Static Ctor
	static Singleton()
	{
                  Type derivedClassType = typeof(T);
		try
		{ 
                    if (IsConstructorCodeInvalid)
                       throw new SingletonException(string.Format("The Singleton class name:{0} should have only private C'tor.", derivedClassType.Name));

		  ConstructorInfo ctorInfo = typeof(T).GetConstructor(
                                     BindingFlags.Instance | 
                                     BindingFlags.NonPublic |
                                     BindingFlags.DeclaredOnly,
				null, CallingConventions.HasThis,
				Type.EmptyTypes, null);

                    _Instance = (T)ctorInfo.Invoke(null);
		}
                  catch (SingletonException){
                     throw;
                  }
		catch (Exception ex){
                     string err = string.Format(
			"Fail to create : {0} . \n Error Message : {1} \n StackTrace: {2}",
			 typeof(T).Name,
			 ex.InnerException != null ? ex.InnerException.Message : ex.Message,
			 ex.StackTrace);
		  throw new SingletonException(err);
		}
	}
	#endregion

	#region Static public
	static public T Instance { get { return _Instance; } }
	#endregion

         #region Private Static Methods
         static private bool IsConstructorCodeInvalid
         {
            get
            {
                foreach (ConstructorInfo ctorInfo in typeof(T).GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance))
                {
                    if (!ctorInfo.IsPrivate)
                        return true;
                }
                return false;
            }
         }
         #endregion

	#region Private Members
	static private T _Instance;
	#endregion
}

错误处理

如果出现错误,则会抛出 SingletonException 对象,存在以下几种情况:

  • 存在公共、内部或受保护的构造函数。
  • 私有构造函数不存在。
  • 初始化派生类时出现问题。
[Serializable]
public class SingletonException : ApplicationException
{
	internal SingletonException(string err)
		: base("Exception while trying to create Singleton.\n " + err) { }
}

 

使用代码

单例设计模式意味着类的单个实例,因此派生类 MySingleton 的构造函数必须是私有的。

 
public class MySingleton:Singleton<MySingleton>
{
 #region Private Ctor
 private MySingleton(){}
 #endregion

 public string Name {get{return "MySingleton";}}
}
© . All rights reserved.