I did this as an exercise just to practice/improve using generics.
Independent of how useful this implementation of a Singleton is, how is my coding in terms of using generics and any other aspect of class design of code style?
void Main()
{
    var a = Singleton<MyClass>.Value;
    var b = Singleton<MyClass, MyClassFactory>.Value;
    var c = Singleton<MyClass>.Value;
    var d = Singleton<MyClass, MyClassFactory>.Value;
    var e = Singleton<MyOtherClass>.Value;
    var f = Singleton<MyOtherClass>.Value;
    var g = Singleton<MyOtherClass, MyOtherFactory>.Value;
    var h = Singleton<MyOtherClass, MyOtherFactory>.Value;
}
class SingletonBase
{
    protected static object Locker = new LockerObject();
}
class Singleton<T> : SingletonBase where T : new() 
{
    static T StaticT;
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = Activator.CreateInstance<Factory<T>>().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}
class Singleton<T, F> : SingletonBase where T : new() where F : IFactory<T>, new()
{
    static T StaticT;
    public static T Value 
    {
        get
        {
            lock (Locker)
            {
                if(StaticT == null)
                {
                    StaticT = new F().Create();
                }
                else
                {
                    Console.WriteLine ("Singleton<T, F>::Value" + typeof(T).Name + " is already created");
                }
            }
            return StaticT;
        }
    }
}
class LockerObject
{
    Guid myGUID;
    public LockerObject()
    {
        this.myGUID = Guid.NewGuid();
        Console.WriteLine ("New LockerObject " + this.myGUID.ToString());
    }
}
interface IFactory<T>
{
    T Create();
}
class Factory<T> : IFactory<T> where T : new()
{
    public T Create()
    {
        Console.WriteLine ("Factory<T>::Create()");  
        return new T();
    }
}
class MyClassFactory : IFactory<MyClass>
{
    public MyClass Create()
    {
        Console.WriteLine ("MyClassFactory::Create()");    
        return new MyClass();
    }
}
class MyClass
{
    public MyClass()
    {
        Console.WriteLine ("MyClass created");
    }
}
class MyOtherClass
{
    public MyOtherClass()
    {
        Console.WriteLine ("MyOtherClass created");
    }
}
class MyOtherFactory : IFactory<MyOtherClass>
{
    public MyOtherClass Create()
    {
        Console.WriteLine ("MyOtherFactory::Create()");    
        return new MyOtherClass();
    }
}
Output:
New LockerObject 36aa2282-d745-43ca-84d2-998a78e39d51 Factory<T>::Create() MyClass created MyClassFactory::Create() MyClass created Singleton<T>::ValueMyClass is already created Singleton<T, F>::ValueMyClass is already created
Tis required to have a public parameterless constructor, anyone can create a new instance of it. Same problem with the version usingIFactory<T>. \$\endgroup\$