为什么new()约束必须要求公共构造函数?

时间:2011-05-12 20:36:03

标签: c# generics .net-4.0 singleton

免责声明:理论问题

  

新约束指定任何   泛型类中的类型参数   声明必须公开   无参数构造函数。

     

来源:http://msdn.microsoft.com/en-us/library/sd2w2ew5(v=vs.80).aspx

如果我希望我的泛型类具有受保护的无参数构造函数,该怎么办?例如,如果我想编写一个Singleton类,我将其“附加”到其他类以使它们成为Singleton,我不希望派生类可以实例化 - 所有内容都应该通过.Instance财产。

internal class Singleton<T> where T : new()
{
    public static T Instance { get; private set; }

    static Singleton()
    {
        Singleton<T>.Instance = new T();
    }
}

internal class OnlyOneOfMe : Singleton<OnlyOneOfMe>
{
    protected OnlyOneOfMe()
    {
    }
}

这样,Singleton<T>能够创建OnlyOneOfMe类的唯一实例,但没有别的可以(除非它是子类)。

“如果通用父类可以访问泛型类型的受保护成员怎么办?”

4 个答案:

答案 0 :(得分:4)

因为这是约束的定义。这有点像询问为什么T : class要求T成为引用类型。根据定义,这是真的。

此外,如果它不是公共构造函数,那么约束点是什么?如果构造函数不是公共的,则接收类型参数T的类将无法调用它。

答案 1 :(得分:2)

您可以使用reflection调用受保护的构造函数。然而,这应该提出警告信号,表明你正在做一些你不应该做的事情。在大多数情况下,您应该能够避免单身并使用dependency injection代替。如果这也不起作用,您可以使用环境上下文模式(see my answer here)。

答案 2 :(得分:1)

如果构造函数受到保护,Singleton将无法调用它。

即使我可以,我也会避免像这样实现单例模式。这很麻烦 - 如果你想要一个继承自抽象的单例类怎么办?

答案 3 :(得分:1)

.NET不会知道您不想接受

class OnlyOneOfMe : Singleton<Other>

作为有效的课程。因为它实际上是有效的,所以它将尝试创建类并需要一个公共的其他构造函数。