публичные переменные против приватных переменных с аксессорами - PullRequest
24 голосов
/ 03 октября 2008

Кто-нибудь еще видел, чтобы люди делали это:

private string _name;
public string Name{ get{ return _name; } set{ _name = value;}}

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

Ответы [ 10 ]

36 голосов
/ 03 октября 2008

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

Обратите внимание, что в C # 3.0 вы можете реализовать свойство без создания вспомогательного поля, например ::

.
public string Name { get; set; }

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

13 голосов
/ 03 октября 2008

Если вы определяете открытый интерфейс со свойством в сборке A, вы можете использовать этот интерфейс в сборке B.

Теперь вы можете изменить реализацию свойства (возможно, извлекая значение из базы данных, а не сохраняя его в поле). Затем вы можете перекомпилировать сборку A и заменить более старую. Сборка В продолжалась бы нормально, потому что интерфейс не изменился бы.

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

Итак, вам лучше начать с свойства изначально. Это инкапсулирует реализацию свойства, предоставляя вам возможность изменять его в будущем, не беспокоясь о том, какие клиенты (включая сборку B) уже в мире используют сборку A. Потому что, если в мире уже есть клиенты. использование сборки А, изменение интерфейса сломало бы всех клиентов. Если они используются другой командой в вашей компании или другой компанией, то они будут недовольны, если вы сломаете их сборки, изменив свой интерфейс!

6 голосов
/ 06 октября 2008

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

6 голосов
/ 03 октября 2008

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

3 голосов
/ 03 октября 2008

Хорошая практика программирования. Это очень распространенный шаблон, который соответствует методологиям проектирования ОО. Открывая открытое поле, вы раскрываете внутреннюю информацию о том, как эти данные хранятся. Вместо этого использование открытого свойства позволяет вам более гибко изменять способ внутреннего хранения данных и не нарушать общедоступный интерфейс. Это также позволяет вам лучше контролировать то, что происходит при обращении к данным (отложенная инициализация, нулевые проверки и т. Д.)

2 голосов
/ 03 октября 2008

Переменные являются частью реализации класса. Свойства более логично представляют интерфейс к нему. В C # 3.0 автоматически реализуемые свойства делают этот процесс легким делом с самого начала.

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

0 голосов
/ 03 октября 2008

Чтобы сохранить высокую степень расширяемости без необходимости повторной компиляции всех ваших сборок, вы хотите использовать общедоступные свойства в качестве методов доступа. Следуя «контракту» или определенному механизму, который описывает, как ваши объекты будут обмениваться данными, будет введен набор правил. Этот контракт обеспечивается интерфейсом и выполняется геттерами и сеттерами вашего класса, которые наследуют этот интерфейс.

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

0 голосов
/ 03 октября 2008

Для инкапсуляции не рекомендуется использовать открытые поля.

http://my.safaribooksonline.com/9780321578815/ch05lev1sec5?displaygrbooks=0

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

0 голосов
/ 03 октября 2008

Общедоступные члены обычно должны быть методами, а не полями. Это просто хорошая практика, и эта практика помогает вам гарантировать, что инкапсулированное состояние ваших объектов всегда находится под вашим контролем.

0 голосов
/ 03 октября 2008

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

...