Singleton模式是最常的设计模式之一,我们会经常写这类代码.因其基本原理就是保存一个静态的对象实例,所以我们便能利用泛型写出一个通用的Singleton类.
代码很简单:
public class Singleton<T>
...{
static readonly T _t;
static Singleton()
...{
_t = Construct();
}
public static T GetInstance()
...{
return _t;
}
private static T Construct()
...{
Type type = typeof(T);
ConstructorInfo ctor;
ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null, new Type[0], new ParameterModifier[0]);
System.Diagnostics.Debug.Assert(ctor != null, "Error in ENLS.Basic.Singleton.Construct().");
return (T)ctor.Invoke(new object[0]);
}
}
因为特化的泛型类是不同的类型,Singleton<Tuple<int>>和Singleton<Tuple<int,long>>不同,所以这两个类中的_t是不同的静态实例.然后在Construct方法中通过反射调用共有或私有的默认构造参数来创建新实例.为什么会有public的构造函数呢,这是为了使用NullObject模式.比如为了方便我要给Tuple基类添加一个方法用来的到空对象
public static Tuple GetNullInstance<_Tuple>() where _Tuple: Tuple
有了这个空对象我就可以更简单的使用前面文章中介绍的遍历控件的函数.
{
return Singleton<_Tuple>.GetInstance();
}
public IEnumerable<Control> Iterator<_Tuple>(Control baseCtl) where _Tuple : Tuple
...{
Tuple tuple = Tuple.GetNullInstance<_Tuple>();
foreach(Control c in baseCtl.Controls)
...{
if (!tuple.HasType(c))
...{
foreach (Control c1 in Iterator<_Tuple>(c))
yield return c1;
}
else
yield return c;
}
}
这样就可以很方便的调用了
foreach (Control c in this.Iterator<Tuple<TextBox, TreeView, CheckBox>>(this))
MessageBox.Show(c.Name);