开发者

Why must the new() constraint require a public constructor?

开发者 https://www.devze.com 2023-03-05 18:34 出处:网络
Disclaimer: Theoretical Question The new constraint specifies that any type argument in a generic class

Disclaimer: Theoretical Question

The new constraint specifies that any type argument in a generic class declarat开发者_JAVA技巧ion must have a public parameterless constructor.

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

What if I wanted my generic class to have a protected parameterless constructor instead? For instance, if I want to write a Singleton class which I "attach" to other classes to make them Singletons, I don't want the derived classes to be instantiable - everything should go through the .Instance property.

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()
    {
    }
}

This way, Singleton<T> is able to create the only instance of the OnlyOneOfMe class, but nothing else can (unless it is a subclass).

"What if a generic parent class could access the generic type's protected members?"


Because that is the definition of the constraint. It's a bit like asking why does T : class require that T be a reference type. It's true by definition.

Additionally, if it weren't a public constructor, what would be the point of the constraint? The class receiving the type parameter T wouldn't be able to call the constructor if it weren't public.


You can call a protected constructor using reflection. However this should raise warning signs that you are doing something you are not supposed to. In most cases, you should be able to avoid a singleton and use dependency injection instead. If that doesn't work either, you can use something like the ambient context pattern (see my answer here).


.NET would not know that you don't want to accept

class OnlyOneOfMe : Singleton<Other>

as a valid class. Since it is actually valid it will try to make the class and needs a public Other constructor.


If the constructor were protected, Singleton wouldn't be able to call it.

And I'd avoid implementing the singleton pattern like that anyway, even if I could. It's messy - what if you wanted a singleton class that inherits from an abstract one?

0

精彩评论

暂无评论...
验证码 换一张
取 消