-3

Doing some work on abstract classes and singletons, I have come across many useful resources from StackOverflow. However, I still have a question regarding the grandchildren of singleton classes.

My singleton code looks like this, taken from the answer on How to abstract a singleton class?, looks like this:

public abstract class Singleton<T> where T : Singleton<T>
{
    private static readonly Lazy<T> _instance;

    static Singleton()
    {
        _instance = new Lazy<T>(() =>
        {
            try
            {
                // Binding flags include private constructors.
                var constructor = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
                return (T)constructor.Invoke(null);
            }
            catch (Exception exception)
            {
                throw new SingletonConstructorException(exception);
            }
        });
    }
    public static T Instance { get { return _instance.Value; } }
}

My children of this class are created with this syntax:

public class SingletonChild : Singleton<SingletonChild>
{
    [code]
}

Now, my question lies here: How does one declare a child of the child class, or a grandchild of the singleton?

I believe it is one of these two, but I'm not sure which:

public class SingletonGrandChild : SingletonChild { [code] }

OR

public class SingletonGrandChild : SingletonChild<SingletonGrandChild> { [code] }

Can anyone provide some insight as to what it would be? Thanks!

  • 2
    Is the fact that the class is a singelton really relevant to the question? Why don't you try it yourself and see? – Zohar Peled Apr 09 '18 at 22:27
  • As soon as you remove the generic from the child, the grandchildren is useless as the generic would be its father. Also, think hardly for the reason you are using singletons at all and specially grandchildren – Camilo Terevinto Apr 09 '18 at 22:29
  • 1
    I've never understood why anyone would make a singleton base class. Singleton is a *pattern*, not *functionality*. Making it a base class saves you maybe three or four lines of repeated code at the expensive of wasting the only shot you have at setting the base class of a type. Just don't do it. A base class is the wrong way to make a singleton in the first place. – Eric Lippert Apr 10 '18 at 00:05

2 Answers2

0

When modeling inheritance, the child class considers the parent class's class definition to create the inheritance relationship. In your case, the correct answer is:

public class SingletonGrandChild : SingletonChild { [code] }

As SingletonChild doesn't declare a generic in its class definition, there is no need to do so when inheriting from it (in fact doing so would cause compilation errors).

I'm not sure what you're trying to accomplish with this setup but in any case, I hope this info helps you in your overall understanding.

Always Learning
  • 2,623
  • 3
  • 20
  • 39
  • 1
    Thanks! The situation I'm in is that I created a template (the abatract class), but I wanted to force all children of it to be singletons as controllers for various things. – Benjamin Kerman Apr 09 '18 at 23:38
0

Neither will work as you intend.

The first approach:

public class SingletonGrandChild : SingletonChild { [code] }
Console.WriteLine(SingletonGrandChild.Instance.GetType()); // prints SingletonChild

The second approach:

public class SingletonGrandChild : SingletonChild<SingletonGrandChild> { [code] }

This will not let you inherit any code from the SingletonChild

If SingletonChild is abstract this will work:

public abstract class SingletonChild<T> : Singleton<T> where T:SingletonChild<T>{ [code] }

public class SingletonGrandChild : SingletonChild<SingletonGrandChild>{ [code] }

If SingletonChild not is abstract I think you have a problem. SingletonGrandChild will be one instance and SingletonChild another. Which means that if the SingletonGrandChild instance access protected fields in the SingletonChild class it will not be the same fields as in SingletonChild instance.

Either way, you should avoid singletons, and avoid inheritance for code reuse (see https://stackoverflow.com/a/9370898/249665).

Fredrik
  • 171
  • 1
  • 7