Абстрактный дизайн класса: почему бы не определить публичные конструкторы? - PullRequest
4 голосов
/ 26 октября 2010

Посмотрите здесь (Дизайн абстрактного класса): http://msdn.microsoft.com/en-us/library/ms229047.aspx

Там написано:

(1) Не определять публичные или защищенные внутренние (Protected Friend в Visual Basic) конструкторыв абстрактных типах.

В C # мы не можем создать экземпляр абстрактного класса.Итак, имеет ли значение определение открытых конструкторов для абстрактных классов в C #?Или не писать публичные конструкторы для абстрактных классов из-за семантического значения?

В нем также говорится:

(2) Определить защищенный или внутренний конструктор в абстрактных классах.

Определить внутренние конструкторы ??В (1) он говорит нам, что не определение внутренних защищенных конструкторов объясняется тем, что «конструкторы с публичной или защищенной внутренней видимостью предназначены для типов, которые могут быть созданы».Разве определение внутренних конструкторов для абстрактных классов не нарушает правила в (1)?

Заранее спасибо.:)

Ответы [ 3 ]

6 голосов
/ 29 ноября 2010

Давайте рассмотрим каждый из случаев.

Рекомендуется:

  • protected - Наиболее очевидный случай - все подклассы могут вызывать конструктор, независимо от того, в какой сборке они находятся (до тех пор, пока сам абстрактный абстрактный класс ) виден им).

  • внутренний - полезно, если вы хотите, чтобы абстрактный тип был публично видимым , но не публично наследуемым . В этом случае вы захотите сделать все не частные конструкторы internal. Только подклассы в той же сборке , что и абстрактный базовый класс, смогут вызывать конструкторы - эффективно, только они смогут наследовать. Другой вариант использования был бы, если бы вы хотели «специальный» конструктор, который должен быть видимым только для подклассов той же сборки.

  • private - Используется в основном для конструкторов 'dirty-work', которые предназначены для других конструкторов абстрактного класса, когда он использует конструктор-цепочку. Единственное другое использование, когда все конструкторы являются закрытыми, - это разрешать создание подклассов только для вложенных классов, которые имеют доступ к закрытым членам типа содержащего.


Не рекомендуется:

  • public - Не полезно, ведет себя идентично to protected. В любом случае, только подклассы могут вызывать конструктор, поскольку базовый класс является абстрактным.

  • защищенный внутренний - Это также ничем не отличается от protected. Уровень доступности protected internal означает защищенный ИЛИ внутренний, не защищенный И внутренний. Однако модификатор internal здесь не имеет смысла - он не предотвращает подклассы, находящиеся вне сборки, от вызова конструктора (при условии, что абстрактный базовый класс является общедоступным), поскольку они могут полагаться на protected доступ, и при этом это не позволяет типам той же сборки, которые являются не подклассами от вызова его (тип является абстрактным).

Ключевым моментом здесь является то, что каждый не private конструктор в абстрактном классе уже в лучшем случае protected. Модификатор vanilla internal усиливает ограничения на то, кто может вызывать конструктор. public и protected internal ничего не достигают, потому что они кажутся ослабляющими ограничения, но на самом деле это не удается.

0 голосов
/ 22 апреля 2015

Прошли годы.Я думаю, что теперь я лучше понимаю этот вопрос.Поэтому я хотел бы добавить еще кое-что помимо превосходного ответа Ани.

В C # мы не можем создать экземпляр абстрактного класса.Итак, имеет ли значение определение открытых конструкторов для абстрактных классов в C #?

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

Определить внутренние конструкторы ??В (1) он говорит нам, что не определение внутренних защищенных конструкторов объясняется тем, что «конструкторы с публичной или защищенной внутренней видимостью предназначены для типов, которые могут быть созданы».Разве определение внутренних конструкторов для абстрактных классов не нарушает правила в (1)?

Если мы хотим, чтобы абстрактный класс наследовался только подклассами в одной сборке, очевидно, мы не можем использовать protected(иначе это может быть унаследовано вне сборки).Теперь у нас есть несколько вариантов выбора:

  • public - Как упоминалось выше, public является вводящим в заблуждение для читателей кода.Не используйте его.

  • private - Мы хотим, чтобы абстрактный класс наследовался подклассами в одной сборке, а не только вложенными подклассами, поэтому private не будет работать.

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

  • внутренняя - вводит в заблуждение для читателей кода, но у нас нет другого выбора.Я бы подумал, что это компромисс .

0 голосов
/ 26 октября 2010

n C #, мы не можем создать экземпляр абстрактного класса.Итак, имеет ли значение определение открытых конструкторов для абстрактных классов в C #?Или не писать публичные конструкторы для абстрактных классов из-за семантического значения?

Точно.Вы не хотите, чтобы пользователь видел доступный конструктор, но когда он его вызывает, он получает ошибку компиляции.

Определить внутренние конструкторы ??В (1) он говорит нам, что не определение внутренних защищенных конструкторов объясняется тем, что «конструкторы с публичной или защищенной внутренней видимостью предназначены для типов, которые могут быть созданы».Разве определение внутренних конструкторов для абстрактных классов не нарушает правила в (1)?

Я считаю, что правило 1 касается public, а protected internal правило 2 - protected и internal,Так что нет пересечения между ними.

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