我正在尝试从Base类实例化一个继承的类。
我尝试过这段代码:
public class BasicClass
{
private static BasicClass instance;
private BasicClass() { }
public static BasicClass Instance
{
get
{
if (instance == null)
{
var dataType = MethodBase.GetCurrentMethod().DeclaringType;
instance = (BasicClass)Activator.CreateInstance(dataType);
}
return instance;
}
}
}
public class MyClass1 : BasicClass
{
}
public class MyClass2 : BasicClass
{
}
然后叫它:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var o = MyClass2.Instance;
Text = o.GetType().Name;
}
}
我的小演示我使用过WinForm应用程序,但这只是用于测试。
我的问题是,我得到了BasicClass
而不是MyClass2
的实例。我可以获得一些MyClass2
答案 0 :(得分:2)
简短回答是:Singleton模式不能被继承。这是因为静态字段(例如,实例)是在特殊的所谓Type Object
中声明的?在你的情况下是BaseType
,因此他们对他们的孩子一无所知
你想要达到什么目标?
您可以实现这样的包装:
public class Singleton<T>
where T:class, new()
{
private static readonly Lazy<T> _instance = new Lazy<T>(()=>new T());
public static T Instance
{
get { return _instance.Value; }
}
}
请参阅下面的答案,它提供了Singleton包装器的酷实现
答案 1 :(得分:2)
我可以获得一些
MyClass2
吗?
不,至少不是你采用的方法。 GetCurrentMethod()
不会在调用者中获取方法,它将为您提供实现getter属性的方法。
此外,请考虑此声明:
private static BasicClass instance;
无论您创建了多少个子类,程序中只有一个instance
。问题是如果MyClass2
创建了一个实例并将其存储在BasicClass.instance
中,那么MyClass1
的实例就无处可去。
您可以采用的一种方法是使用将子类型映射到实例的字典,以及用于访问它们的通用方法,如下所示:
private static IDictionary<Type,BasicClass> instances = new Dictionary<Type,BasicClass>();
...
public static T GetInstance<T>() where T : BasicClass {
BasicClass res;
if (!instances.TryGetValue(typeof(T), out res)) {
res = (BasicClass)Activator.CreateInstance(typeof(T));
instances.Add(typeof(T), res);
}
return (T)res;
}
...
var o = MyClass2.GetInstance<MyClass2>();
答案 2 :(得分:2)
您可以创建模板化基类:
public abstract class Singleton<T> where T : class
{
private static readonly Lazy<T> instance = new Lazy<T>(() => CreateInstance());
public static T Instance { get { return instance.Value; } }
private static T CreateInstance()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
然后继承它:
public class MyClass1 : Singleton<MyClass1>
{
}