c#

时间:2018-04-09 22:13:12

标签: c# .net singleton abstract-class

在抽象类和单例上做了一些工作,我从StackOverflow中遇到了许多有用的资源。但是,我仍然对单身类的孙子有疑问。

我的单例代码如下所示,取自How to abstract a singleton class?上的答案,如下所示:

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; } }
}

我的这类孩子是用这种语法创建的:

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

现在,我的问题在于:如何宣布儿童班的孩子或单身人士的孙子?

我相信这是其中之一,但我不确定:

public class SingletonGrandChild : SingletonChild { [code] }

OR

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

任何人都能提供一些有关它会是什么的见解吗? 谢谢!

2 个答案:

答案 0 :(得分:0)

在建模继承时,子类会考虑父类的class定义来创建继承关系。在您的情况下,正确答案是:

public class SingletonGrandChild : SingletonChild { [code] }

由于SingletonChild没有在其类定义中声明泛型,因此在继承它时不需要这样做(实际上这样做会导致编译错误)。

我不确定您要通过此设置完成什么,但无论如何,我希望此信息可以帮助您全面理解。

答案 1 :(得分:0)

两者都不会按预期工作。

第一种方法:

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

第二种方法:

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

这不允许您继承SingletonChild的任何代码

如果SingletonChild是抽象的,这将起作用:

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

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

如果SingletonChild不是抽象的,我认为你有问题。 SingletonGrandChild将是一个实例而SingletonChild将是另一个实例。这意味着如果SingletonGrandChild实例访问SingletonChild类中的受保护字段,它将不会与SingletonChild实例中的字段相同。

无论哪种方式,你都应该避免单例,并避免继承代码重用(参见https://stackoverflow.com/a/9370898/249665)。