Почему предпочитаете свойства для общедоступных переменных?
Другие значения проверки работоспособности в сеттерах есть более основополагающая причина предпочтения свойств общедоступным переменным?
Ответы
Ответ 1
У нас была эта тема раньше, но я ничего не могу найти сейчас.
Вкратце: ваши потребности могут измениться: там, где нет проверки на здравомыслие, в будущем может потребоваться. Однако, если вы измените свои общедоступные поля на свойства, это приведет к разрыву бинарной совместимости: каждый клиент, который использует ваш код/библиотеку, должен будет повторно скомпилировать.
Это плохо, потому что это потенциально дорого стоит.
Использование свойств с самого начала позволяет избежать этой проблемы. Это даже считается для кода, который не является частью библиотеки. Зачем? Потому что вы никогда не знаете: код (даже если он очень специфичен для домена!) Может оказаться полезным, поэтому вы хотите реорганизовать его в библиотеку. Этот процесс рефакторинга, очевидно, значительно упрощается, если вы уже используете свойства вместо общедоступных/защищенных полей.
Кроме того, запись общедоступных свойств в С# 3.0 легко, потому что вы можете просто использовать автоматически реализованные свойства, сохраняя довольно много кода:
public DataType MyProperty { get; set; }
Внедрит для вас необходимое поле поддержки и код getter/setter.
Я добавлю личное примечание: поведение .NET в этом отношении несколько лениво. Компилятор может просто менять открытые поля на свойства "на лету", тем самым избегая проблемы. VB6 уже сделал это для классов, подверженных COM, и я не вижу абсолютно никаких оснований для того, чтобы VB.NET и С# не делали то же самое. Возможно, кто-то из команд компилятора (Джаред?) Мог бы прокомментировать это.
Ответ 2
В двух словах:
- Вы можете управлять доступом (только для чтения,
writeonly, чтение/запись)
- Вы можете проверить значения при настройке
свойство (отметьте нуль и т.д.)
- Вы можете выполнить дополнительную обработку,
такие как ленивая инициализация
- Вы можете изменить основные
реализация. Например,
собственность может быть поддержана членом
теперь переменная, но вы можете ее изменить
для поддержки строки DB без
нарушая любой код пользователя.
Ответ 3
Джефф Этвуд рассказал об этом:
Имеются веские причины для создания тривиального свойства, как показано выше:
- Отражение работает по-разному по переменным и свойствам, поэтому, если вы полагаетесь на отражение, проще использовать все свойства.
- Вы не можете привязывать данные к переменной.
- Изменение переменной в свойстве нарушение изменений.
Это позор там бессмысленного трения между переменными и свойствами; большую часть времени они делают то же самое. Кевин Денте предложил немного нового синтаксиса, который дал бы нам лучшее из обоих миров:
public property int Name;
Однако, если различие между переменной и собственностью является такой постоянной проблемой, мне интересно, подходит ли более радикальное решение. Не могли ли мы перевернуть переменные целиком в пользу свойств? Не обладают ли свойства точно так же, как переменные, но с улучшенным гранулированным контролем над видимостью?
Ответ 4
Изменение поля для свойства в будущем считается изменением. Полями считаются детали реализации классов и раскрытие их публично нарушает инкапсуляцию.
Ответ 5
Если вы работаете в закрытой среде - вы не разрабатываете SDK, все классы используются в рамках одного и того же проекта - нет разницы.
Обычный аргумент состоит в том, что "в будущем вам может понадобиться выполнить некоторую проверку значений, так что проще с свойствами". Я вообще не покупаю его.
Использование общедоступных полей является более читаемым, менее декоративным и более простым в использовании.
Ответ 6
Вы также можете защитить доступ к записи и разрешить доступ к чтению с помощью свойства:
public int Version { get; private set; }
Ответ 7
Использование свойств делает ваш код более ориентированным на объект. Предоставляя переменные-члены public, вы подвергаете свою реализацию.
Также см. ссылку из руководства по программированию на С#
Ответ 8
Да.
Рассмотрим общедоступную varibale, которая теперь содержит строку, вы можете просто установить ее. Однако, если вы решите, что эта открытая переменная должна содержать объект, который должен быть инициализирован строкой, вам придется изменить весь свой код с помощью исходного объекта. Но если бы вы использовали setter, вам нужно было бы изменить установщик для инициализации объекта с предоставленной строкой.