Основная идея заключается в том, что «поле» (переменная уровня экземпляра), которое объявлено как защищенное, вероятно, более заметно, чем должно быть, и менее «защищено», чем вам может показаться. В C / C ++ / Java / C # отсутствует модификатор доступа, который эквивалентен «доступным только дочерним классам в одной сборке», что дает вам возможность определять свои собственные дочерние элементы, которые могут получить доступ к полю в вашей сборке, но не разрешать детям, созданным в других сборках, одинаковый доступ; C # имеет внутренние и защищенные модификаторы, но их объединение делает доступ «внутренним или защищенным», а не «внутренним и защищенным». Таким образом, защищенное поле доступно любому ребенку, независимо от того, написали ли вы этот ребенок или кто-то другой. Защищен, таким образом, открытая дверь для хакера.
Кроме того, поля по определению практически не имеют проверки, присущей их изменению. в C # вы можете сделать один readonly, что делает типы значений фактически постоянными и ссылочные типы не могут быть повторно инициализированы (но все еще очень изменчивы), но это все. Как таковые, даже защищенные, ваши дети (которым вы не можете доверять) имеют доступ к этому полю и могут установить для него что-то недопустимое, что делает состояние объекта несовместимым (что-то, чего следует избегать).
Принятый способ работы с полями - сделать их приватными и получить к ним доступ с помощью свойства и / или метода получения и установки. Если все потребители класса нуждаются в значении, сделайте получатель (по крайней мере) публичным. Если это нужно только детям, защитите добытчик.
Другой подход, который отвечает на вопрос, это спросить себя; почему код в дочернем методе должен иметь возможность напрямую изменять данные моего состояния? Что это говорит об этом коде? Это аргумент "вертикального расстояния" на его лице. Если в дочернем элементе есть код, который должен напрямую изменять родительское состояние, то, возможно, этот код должен в первую очередь принадлежать родителю?