Win64Windows 2008Windows VistaWindows 7Windows 2003Win32.NET 3.0设计 / 图形架构师.NET4Windows XP.NET 2.0.NET 3.5C# 2.0初学者C# 3.0C# 4.0中级开发Windows.NETC#
通用单例设计模式






2.45/5 (6投票s)
通用单例设计模式 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";}}
}