internal
выставляет его другим классам в той же сборке, что я не хочу делать
Мой совет: преодолеть этот страх и пометить его internal
,
Я слышал этот запрос о возможности - что C # реализует семантику друзей в стиле C ++ - много-много раз.Эта функция обычно мотивируется тем, что «если я разрешу любому классу в моей сборке праздновать внутреннее состояние, мои коллеги будут злоупотреблять этой привилегией».
Но ваши коллеги уже имеют возможность злоупотреблять этой привилегией.потому что ваши коллеги уже могут добавлять друзей (в C ++) или создавать внутренние методы, которые являются задними дверями (в C #).
Система доступности C # просто непредназначен для защиты вас от сценариев, в которых люди, имеющие доступ для записи к исходному коду, враждебны вашим интересам.Точно так же, как private
означает «это деталь реализации этого класса», а protected
означает «это деталь реализации этой иерархии», internal
означает «это деталь реализации этой сборки».несут ответственность за правильную работу этой сборки. Нельзя доверять разумному использованию своих полномочий, найдите лучших коллег. Если вашим типам необходим доступ к внутренним деталям друг друга для правильной работы сборки в целом, - это то, что internal
предназначен для , поэтому используйте его.
Или, другими словами, это социальная проблема, а не техническая проблема, поэтому вы должны решить ее, применяя социальное давление .Система специальных возможностей C # не предназначена для решения проблем, которые должны решаться при проверке кода. Если ваши коллеги злоупотребляют своими привилегиями, то время проверки кода - это время, когда они прекращаются, так же, как вы использовали бы проверку кода, чтобы не допустить их добавления.любой другой плохой код для вашего проекта.
Чтобы ответить на ваш конкретный вопросstions:
я беспокоюсь, что что-то еще может унаследовать от Cycle;Можно ли предотвратить это, сделав конструктор для Cycle частным
Да, абстрактный класс может иметь закрытый конструктор, и тогда единственными производными типами являются вложенные типы.
Я использую этот шаблон довольно часто и делаю вложенные типы частными,В C # плохо публиковать вложенный тип, который является публичным.
В сторону: Обычно я делаю так, чтобы создавать "классы дел", такие как:
abstract class ImmutableStack<T>
{
private ImmutableStack() { }
private sealed class EmptyStack : ImmutableStack<T> { ... }
private sealed class NormalStack : ImmutableStack<T> { ... }
и так далее.Это хороший способ сделать детали реализации типа распределенными по нескольким классам, но все же инкапсулированными в один класс.
Я просто параноик?
Это звучит для меня как да.