2011-05-12 98 views
1

免责声明:理论问题

新的约束规定,在泛型类 声明任何 类型参数必须有一个公共 参数构造函数。为什么new()约束需要公共构造函数?

来源: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类的唯一实例,但没有什么可以(除非它是一个子类)。

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

+7

如果构造函数被保护,你打算如何调用它? – 2011-05-12 20:37:27

+0

我知道它不被支持,但我的思考过程是:“如果派生类具有受保护的构造函数,那么泛型类(父类)就可以看到它,因此它不需要公开,对不对?” – 2011-05-12 20:44:18

+1

不,错了。受保护只能在一个方向上工作。只有后代才能访问受保护的构造函数,基类完全不知道它们。 – 2011-05-12 20:45:29

回答

1

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

而且即使我可以,我也会避免像那样执行单例模式。这很麻烦 - 如果你想要一个从抽象类继承的单例类呢?

4

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

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

+0

是的,我意识到“事情就是这样。”我在问为什么它不能得到保护。 'T:class'根本不一样。这个约束非常具体,因为它必须是。 new()约束是过于具体的IMO,因为泛型类能够访问派生类的受保护成员,包括它的构造函数。 – 2011-05-12 20:44:45

+0

@Josh M. Singleton将能够访问T上受保护的构造函数的唯一方法是,如果Singleton继承自T - 在这种情况下,使用泛型没有意义。 – reavowed 2011-05-12 20:54:00

+0

我知道,这更像是一个理论问题,我明白为什么它不能这样工作。我躲过了“如果一个通用父类可以访问泛型类型的受保护成员呢?” – 2011-05-12 21:13:49

1

.NET不会知道你不想接受

class OnlyOneOfMe : Singleton<Other> 

为有效类。由于它实际上是有效的,它会尝试创建类并需要一个公共的其他构造函数。

2

您可以使用reflection调用受保护的构造函数。但是,这应该会引发警告信号,表明您正在做某些您不应该做的事情。在大多数情况下,您应该能够避免使用单身人士,而应该使用dependency injection。如果这也不起作用,您可以使用类似环境上下文模式(see my answer here)。

相关问题