Jens Borrisholt
Jens Borrisholt

Reputation: 6402

Create inherited Class from BaseClass

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

Answers (3)

Alex Voskresenskiy
Alex Voskresenskiy

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

Radin Gospodinov
Radin Gospodinov

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Related Questions