Reputation: 6402
I'm trying to instantiate an inherited class from a Base class.
I have tried with this code:
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
{
}
And then call it :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var o = MyClass2.Instance;
Text = o.GetType().Name;
}
}
I my small demo I've used a WinForm application but that's just for testing.
My problem is that I get an instance of BasicClass
not MyClass2
Can I some how get MyClass2
Upvotes: 0
Views: 63
Reputation: 2233
Short answer is: Singleton pattern cannot be inherited. This is because static fields (Instance, for ex.) are declared in special so-called Type Object
? which in your case is BaseType
and so they no nothing about their children
What do you want to achieve?
You can implement a wrapper like this:
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; }
}
}
See answer below, which provides cool implementation of Singleton wrapper
Upvotes: 2
Reputation: 2323
You can create a templated base class:
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;
}
And then inherit it:
public class MyClass1 : Singleton<MyClass1>
{
}
Upvotes: 2
Reputation: 726579
Can I some how get
MyClass2
?
No, at least not with the approach that you took. GetCurrentMethod()
will not get you the method in the caller, it will give you the method that implements the getter property.
Moreover, consider this declaration:
private static BasicClass instance;
There's only one instance
in your program, no matter how many subclasses you create. The problem is that if MyClass2
creates an instance and stores it in BasicClass.instance
, there's no place for MyClass1
's instance to go.
One approach that you could take would be using a dictionary that maps subtypes to instances, and a generic method for accessing them, like this:
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>();
Upvotes: 2