我有一个声明如下的类:
public class Eq
{
public bool Equals(ValI x, ValI y)
{
return nilnul.num.ord.Eq.Singleton.Equals( x , y);
//throw new NotImplementedException();
}
public int GetHashCode(ValI obj)
{
return nilnul.num.ord.Eq.Singleton.GetHashCode(obj);
throw new NotImplementedException();
}
static public Eq Singleton=SingletonByDefault<Eq>.Instance;
}
而SingletonByDefault看起来像:
public class SingletonByDefault<YourClass>
where YourClass:new()
//where YourClass:class
{
static protected YourClass _Instance= new YourClass();
static public YourClass Instance
{
get
{
return _Instance;
}
}
protected SingletonByDefault() {
}
}
在大多数情况下,当我访问Eq.Singleton成员时,没关系。 但是在某种情况下,我得到了一个空引用异常,它说Eq.Singleton为空。
当我将类Eq的静态“Singleton”字段更改为:
//...
static public Eq Singleton{
get{
return SingletonByDefault<Eq>.Instance;
}
}
//....
异常消失了 - 至少目前是这样。
我怀疑错误是由于静态字段初始化的顺序造成的。现在我的理解是:
1)Eq.Singleton和SingletonByDefault._Instance初始化为null。
2)当我访问Eq.Singleton时,Eq.Singleton初始化为SingletonByDefault.Instance,但是
2.1)从现在开始我访问SingletonByDefault.Instance(然后访问SingletonByDefault._Instance),SingletonByDefault._Instance被初始化为新的Eq()。
3)Eq.Singleton现在将返回“new-ed Eq()”。但
3.1)为什么它是空的?
所以我的理解一定出错了。有人会给我一些启示吗?
答案 0 :(得分:-1)
微软自己的System.Lazy&lt;&gt; class提供了您需要的单例模式,如下所示。
public static class MySingletons
{
private static Lazy<Eq> _eq = new Lazy<Eq>( CreateEq );
private static Eq CreateEq()
{
return new Eq();
}
static public Eq Eq { get{ return _eq.Value; }}
}
// usage
var eq = MySingletons.Eq
更新:这是提问者要求的更高级别的通用包装。这消除了一些重复代码,其中单例类支持基本参数较少的构造函数。
public static class MySingletons
{
static SingletonByLazy<Eq> _eq = new SingletonByLazy<Eq>();
static public Eq Eq
{
get
{
return _eq.Singlton;
}
}
}
public class SingletonByLazy<T> where T: new()
{
Lazy<T> _singltonWrapped = new Lazy<T>( CreateSingleton );
static T CreateSingleton()
{
return new T();
}
public T Singlton
{
get
{
return _singltonWrapped.Value;
}
}
}