Являются ли защищенные свойства злыми?

Вводный фрагмент кода:

```
class BaseClass
{
    protected Foo MyFoo { get; }
}

class ChildClass : BaseClass
{
    void SomeMethod()
    {
        MyFoo.DoStuff();
        //Here, I have no idea that MyFoo is not defined in this class,
        //but rather in the base class.
    }
}

```

Проблема/дискуссия заключается в том, что вам нужно либо знать,
либо проверять вручную, где MyFoo определен. И вам лучше
использовать два частных поля, один в базовом классе, в дочернем
классе.

В нашем случае большую часть времени эти свойства поступают из
[инъекции зависимостей](https://en.wikipedia.org/wiki/Dependency_injection) и доступны в
конструктор обоих классов. Поэтому очень просто просто сопоставить
их с частными свойствами из этого конструктора, а не наследовать
его из базового класса, что также менее понятно.

Есть ли у меня хорошая практика? Какой у вас там опыт?

Основной вопрос. Являются ли защищенные свойства просто плохой
привычкой, и я должен всегда искать частные поля?

Это будет против меня, когда будет проведено тестирование?

Это считается чистым/нечистым кодом?

Я не думаю, что дублирование свойства в подклассе (и его
конструкторе) на самом деле является лучшей альтернативой. Для
фактических свойств чтения/записи, которые не могут даже дать такую
же функциональность, а для введенных только для чтения свойств,
как в вашем случае (возможно, какой-то сервис), это не имеет
большого значения, где это определено. Кроме того, ваша IDE может
легко вам это показать.

В принципе, способ взглянуть на это заключается в следующем:

* Защищенные поля являются частью API класса для подкласса, как и
методы.
* Защищенные поля, которые фактически содержат изменяемые данные,
могут определенно привести к тому, что код трудно понять, но
поэтому могут содержать защищенные методы, когда они
переопределяются в подклассах, но вызывается в суперклассе.
* Проблема здесь не в защищенных полях или методах, проблема
заключается в подклассе. Его следует использовать осторожно и
экономно.
* Эмпирическое правило, которое я только что сделал на месте:
либо суперкласс должен быть очень маленьким и простым, либо
подклассом. И глубокие иерархии наследования плохие.



> 
> вам нужно либо знать, либо проверять вручную, где определен
> MyFoo
> 
> 
> 

Но как это специфично для *защищенных свойств* ? То же
самое верно для методов и действительно *любой* публичный
член. Одной из основных причин наследования является отсутствие
необходимости повторять одно и то же для каждого конкретного типа.
Таким образом, вы можете иметь общий базовый тип, который содержит
определения базового поведения и базового хранилища.

Защищенное свойство или область просто сообщает вам, что это
внутренняя деталь реализации, которая *вероятна* должна быть
релевантна для подклассов. В некотором роде, это фактически говорит
вам больше, чем полностью несвязанные частные свойства на каждом
уровне.

И компилятор уже знает, где он определен и как его доступно. И
хорошие редакторы расскажут вам, что во время разработки, поэтому
нет необходимости «проверять вручную». Кроме того, при наследовании
типа я бы ожидал, что вам будет комфортно его интерфейс, поэтому вы
*знаете* , что есть защищенные члены, которые вы можете
использовать.

> 
> В нашем случае эти свойства исходят от инъекции зависимостей
> 
> 
> 

Это может быть только мое мнение, но я всегда использовал бы
`readonly` *поля* для зависимостей, а не для
свойств.

> 
> Так что очень просто просто сопоставить их с частными свойствами
> из этого конструктора
> 
> 
> 

Конечно, у вас может быть личное поле на каждом уровне иерархии
типов. Но это также дублирует использование памяти, необходимое для
отслеживания этих данных. И если вы на мгновение игнорируете тот
факт, что это неизменные зависимости, введенные в конструктор,
базовый класс, который не может *изменить* , значение для
его подклассов также может привести к проблемам.

> 
> Являются ли защищенные свойства просто вредной привычкой, и
> должен ли я всегда использовать частные поля?
> 
> 
> 

Здесь есть два вопроса: [Свойство против поля](https://stackoverflow.com/questions/653536/difference-between-property-and-field-in-c-sharp-3-0) и `protected` vs
`private` . Чтобы ответить на последнее: используйте то,
что имеет смысл в смысле инкапсуляции. Если ваш базовый тип имеет
фактические внутренние API, которые могут использовать подклассы,
они должны быть защищены. Но вы не должны просто делать зависимую
защиту *на всякий случай* .



> 
> Являются ли защищенные свойства злыми?
> 
> 
> 

Нет. Защищенные свойства *smelly* , но не *evil* .
То есть, они должны заставить вас подумать: «Я правильно моделирую
это?» Один считает, что свойство является частью общей площади
поверхности модели, а поле является частным элементом реализации
модели. Поскольку «защищенный» просто означает «частную деталь
реализации этой иерархии», можно ожидать, что защищенные поля, а не
защищенные свойства.

Тем не менее, защищенные свойства не являются
*неправильными* ; они просто признак того, что, возможно,
вам нужно подумать о своем дизайне немного сложнее.

> 
> Здесь я не знаю, что MyFoo не определен в этом классе, а скорее
> в базовом классе.
> 
> 
> 

Конечно, вы это знаете. Вы можете прочитать исходный код класса
и ясно видеть, что такого свойства нет. И вы можете «перейти к
определению» и перейти к исходному коду для свойства.

> 
> Проблема/дебаты состоят в том, что вам нужно либо знать, либо
> проверять вручную, где определен MyFoo. </Р>
> 
> 
> 

Нет, нет. Почему, по-вашему, вы должны знать, где это
определено?

> 
> И вам лучше использовать 2 частных поля, один в базовом классе,
> в дочернем классе.
> 
> 
> 

Нет, я не согласен с этим. Возможно, вам лучше использовать
защищенное поле в базовом классе.

> 
> Являются ли защищенные свойства просто вредной привычкой, и
> должен ли я всегда использовать частные поля?
> 
> 
> 

Если вы обнаружите, что пишете много защищенных свойств, я бы
спросил, действительно ли они лучше моделируются как защищенные
поля. Помните, что *свойство должно моделировать свойство
моделируемой вещи* . Если вы пишете класс `Car` ,
тогда его свойства должны быть *свойствами автомобиля* .
Каковы свойства *автомобиля* и *также детали реализации
иерархии автомобилей* ? Я не могу думать ни о чем, что есть обо
всех этих вещах, и поэтому, возможно, не должно быть защищенных
свойств.