Защищенные участники/поля - действительно это плохо?

Теперь при чтении соглашений о присвоении имен в MSDN для C#, Вы заметите, что он указывает, что свойства всегда предпочитаются по общедоступным и защищенным полям. Мне даже сказали некоторые люди, что Вы никогда не должны использовать общедоступные или защищенные поля. Теперь я соглашусь, что должен все же найти причину, в которой я должен иметь общедоступное поле, но являюсь защищенными полями действительно это плохо?

Я вижу его, если необходимо удостовериться, что определенные проверки проверки выполнены при получении/установке значения однако много времени, это походит просто на дополнительные издержки, по-моему. Я имею в виду, позволяет, говорят, что у меня есть класс GameItem с полями для базового имени, prefixName, и suffixName. Почему я должен взять издержки обоих созданий свойств (C#) или методы доступа и хит производительности, я произошел бы (если я делаю это для каждого поля в приложении, я уверен, что это было бы, складывают в меньше немного особенно на определенных языках как PHP или определенные приложения с производительностью являются важными как игры)?

31
задан whytheq 28 August 2014 в 09:43
поделиться

6 ответов

Неужели защищенные элементы / поля настолько плохи?

Нет. Они намного хуже.

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

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

Лучший способ поделиться информацией с производными классами - это свойство , доступное только для чтения ]:

protected object MyProperty { get; }

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

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

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

80
ответ дан 27 November 2019 в 21:25
поделиться

Что касается полей и свойств, я могу придумать две причины для предпочтения свойств в общедоступном интерфейсе (защищенный также является общедоступным в том смысле, что его может видеть кто-то другой, а не только ваш класс).

  • Раскрытие свойств дает вам способ скрыть реализацию. Это также позволяет вам изменять реализацию, не изменяя код, который ее использует (например, если вы решите изменить способ хранения данных в классе)

  • . Многие инструменты, которые работают с классами с использованием отражения, сосредотачиваются только на свойствах (например, Я думаю, что некоторые библиотеки для сериализации так работают).Последовательное использование свойств упрощает использование этих стандартных инструментов .NET.

Относительно накладных расходов:

  • Если геттер / сеттер является обычным однострочным фрагментом кода, который просто считывает / устанавливает значение поля, тогда JIT должен иметь возможность встроить вызов, чтобы не было потери производительности .

  • Синтаксические накладные расходы значительно снижаются, когда вы используете автоматически реализуемые свойства (C # 3.0 и новее), поэтому я не думаю, что это проблема:

     protected int SomeProperty {get; установленный; }
    

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

6
ответ дан 27 November 2019 в 21:25
поделиться

OK, время понижать голос.

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

  • Другое дело, что свойства хороши тем, что в них можно ставить точки останова, чтобы перехватывать события получения/установки и выяснять, откуда они берутся.

Остальные аргументы беспокоят меня следующим образом:

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

  • Они основаны на идее, что структуры данных имеют множество противоречивых состояний и должны быть защищены от блуждания или попадания в такие состояния. Поскольку (как мне кажется) структурам данных уделяется слишком много внимания в современном преподавании, то обычно они не нуждаются в таких защитах. Гораздо предпочтительнее минимизировать структуру данных, чтобы она была нормализована и не имела противоречивых состояний. Тогда, если член класса изменяется, он просто изменяется, а не повреждается. В конце концов, как-то много хороших программ было/есть написано на C, и они не сильно пострадали от отсутствия защит.

  • Они основаны на защитном кодировании, доведенном до крайности. Они основаны на идее, что ваши классы будут использоваться в мире, где ничьему чужому коду нельзя доверять, чтобы он не загубил ваш материал. Я уверен, что есть ситуации, когда это правда, но я их не встречал. Что я видел, так это ситуации, когда все было ужасно усложнено, чтобы обойти защиту, в которой не было необходимости, и чтобы попытаться защитить согласованность структур данных, которые были ужасно переусложнены и ненормированы.

28
ответ дан 27 November 2019 в 21:25
поделиться

Публичные и/или защищенные поля плохи тем, что ими можно манипулировать извне объявляющего класса без проверки; таким образом, можно сказать, что они нарушают принцип инкапсуляции объектно-ориентированного программирования.

Когда вы теряете инкапсуляцию, вы теряете контракт объявляющего класса; вы не можете гарантировать, что класс ведет себя так, как предполагалось или ожидалось.

Использование свойства или метода для доступа к полю позволяет сохранить инкапсуляцию и выполнить контракт объявленного класса.

5
ответ дан 27 November 2019 в 21:25
поделиться

На самом деле это зависит от того, является ли ваш класс классом данных или классом поведения.

Если вы разделяете свое поведение и данные, то можно будет раскрыть данные ваших классов данных, если они не имеют поведения.

Если класс является классом поведения, он не должен предоставлять какие-либо данные.

0
ответ дан 27 November 2019 в 21:25
поделиться

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

Но когда я на работе, это совсем другая история.

0
ответ дан 27 November 2019 в 21:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: