Почему для ограничения new () требуется открытый конструктор? - PullRequest
2 голосов
/ 13 мая 2011

Отказ от ответственности: теоретический вопрос

Новое ограничение указывает, что любой аргумент типа в объявлении универсального класса должен иметь открытый конструктор без параметров.

Источник: http://msdn.microsoft.com/en-us/library/sd2w2ew5(v=vs.80).aspx

Что если бы я хотел, чтобы в моем универсальном классе вместо этого был защищенный конструктор без параметров?Например, если я хочу написать класс Singleton, который я «присоединяю» к другим классам, чтобы сделать их Singleton s, я не хочу, чтобы производные классы были инстанцируемыми - все должно проходить через свойство .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 ]

4 голосов
/ 13 мая 2011

Потому что это определение ограничения.Это немного похоже на вопрос, почему T : class требует, чтобы T был ссылочным типом.Это верно по определению.

Кроме того, если бы это не был публичный конструктор, в чем смысл ограничения?Класс, получающий параметр типа T, не сможет вызвать конструктор, если он не будет общедоступным.

2 голосов
/ 13 мая 2011

Вы можете вызвать защищенный конструктор, используя отражение .Однако это должно поднять предупреждающие признаки того, что вы делаете что-то, чего не должны делать.В большинстве случаев вы должны быть в состоянии избежать одиночного перехода и использовать вместо него внедрение зависимостей .Если это тоже не сработает, вы можете использовать что-то вроде шаблона окружающего контекста ( см. Мой ответ здесь ).

1 голос
/ 13 мая 2011

.NET не будет знать, что вы не хотите принимать

class OnlyOneOfMe : Singleton<Other>

в качестве допустимого класса.Поскольку он действительно действителен, он попытается создать класс и нуждается в общедоступном конструкторе Other.

1 голос
/ 13 мая 2011

Если бы конструктор был защищен, Синглтон не смог бы его вызвать.

И я бы так или иначе не стал бы реализовывать шаблон синглтона, даже если бы мог.Это грязно - что, если вам нужен одноэлементный класс, который наследуется от абстрактного?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...