Я только что понял, что конструкцию свойства C # можно также использовать с модификатором частного доступа:
private string Password { get; set; }
Хотя это технически интересно, я не могу себе представить, когда бы я использовал его, поскольку личное поле требует еще меньше церемоний :
private string _password;
и я не могу себе представить, когда мне когда-нибудь понадобится иметь возможность получить, но не установить или установить, но не получить личное поле:
private string Password { get; }
или
private string Password { set; }
но, возможно, есть сценарий использования с вложенными / унаследованными классами или, возможно, где get / set может содержать логику, а не просто возвращать значение свойства, хотя я бы хотел сохранить свойства строго простыми и позволить явным методам выполнять любую логику, например GetEncodedPassword()
.
Кто-нибудь использует частные свойства в C # по какой-либо причине, или это просто одна из тех технически возможных, но редко используемых в коде конструкций?
добавление
Хорошие ответы, прочитав их, я выбрал эти варианты использования для частных объектов:
- когда приватные поля нужно лениво загружать
- когда приватные поля нуждаются в дополнительной логике или являются вычисляемыми значениями
- поскольку частные поля могут быть сложными для отладки
- для того, чтобы «представить себе контракт»
- внутренне преобразовать / упростить открытое свойство как часть сериализации
- обертывание глобальных переменных для использования внутри вашего класса
источник
Ответы:
Я использую их, если мне нужно кэшировать значение и хочу его лениво загрузить.
источник
return _password ?? (_password = CallExpensiveOperation());
return _password ?? (_password = CallExpensiveOperation());
с тех пор. Или на самом деле Решарпер предпочитает это :).private string Password => _password ?? (_password = CallExpensiveOperation());
private string Password => _password ??= CallExpensiveOperation();
CallExpensiveOperation();
вызывается во время построения / инициализации содержащего объекта, а не при первом обращении к свойству.Основное использование этого в моем коде - ленивая инициализация, как уже упоминали другие.
Другая причина закрытых свойств над полями состоит в том, что частные свойства гораздо, гораздо проще отлаживать, чем частные поля. Я часто хочу знать такие вещи, как «это поле неожиданно устанавливается; кто первый, кто устанавливает это поле?» и это намного проще, если вы можете просто поставить точку останова на сеттере и нажать кнопку go. Вы можете поставить вход в систему там. Вы можете поместить показатели производительности там. Вы можете включить проверки согласованности, которые выполняются в отладочной сборке.
По сути, это сводится к следующему: код гораздо более мощный, чем данные . Любая техника, которая позволяет мне писать нужный мне код, хороша. Поля не позволяют писать код в них, свойства делают.
источник
Я лично использую это, даже когда мне не нужна логика для получения или установки свойства. Использование свойства, даже частного, действительно помогает вашему коду в будущем, так что вы можете добавить логику к получателю позже, если потребуется.
Если я чувствую, что свойство может в конечном итоге потребовать дополнительной логики, я иногда заключаю его в приватное свойство вместо использования поля, просто чтобы позже мне не пришлось менять свой код.
В полу-связанном случае (хотя и отличающемся от вашего вопроса) я очень часто использую частные сеттеры для открытых свойств:
Это дает вам общедоступный метод получения, но сохраняет его в частном порядке.
источник
Одно хорошее использование для частных свойств только для получения - это вычисленные значения. Несколько раз у меня были свойства, которые доступны только для чтения и просто делали вычисления над другими полями в моем типе. Он не достоин метода и не интересен другим классам, поэтому это частная собственность.
источник
Ленивая инициализация - это то место, где они могут быть аккуратными, например
Тогда вы можете написать:
this.MyType
везде, а неthis.mytype.Value
инкапсулировать тот факт, что он лениво создается в одном месте.Обидно то, что C # не поддерживает определение области поддержки для свойства (т.е. объявляет его внутри определения свойства), чтобы полностью скрыть его и обеспечить доступ к нему только через свойство.
источник
field-declaration
рамкахaccessor-declarations
занимает долгое время номер 1 в моем списке пожеланий C #. Если бы вы могли спроектировать и реализовать это в какой-то (реальной) будущей версии, то я испеку вам торт.Единственное использование, которое я могу придумать
источник
private bool IsPasswordSet() { return !String.IsNullOrEmpty(_password); }
Свойства и поля не один в один. Свойство относится к интерфейсу класса (говорит о его открытом или внутреннем интерфейсе), а поле - к реализации класса. Свойства не должны рассматриваться как способ просто раскрыть поля, они должны рассматриваться как способ раскрыть намерение и цель класса.
Точно так же, как вы используете свойства, чтобы представить своим клиентам контракт на то, что составляет ваш класс, вы также можете представить контракт себе по очень похожим причинам. Так что да, я использую частные свойства, когда это имеет смысл. Иногда частное свойство может скрывать детали реализации, такие как отложенная загрузка, тот факт, что свойство действительно представляет собой конгломерат нескольких полей и аспектов, или что свойство должно быть виртуально создано с каждым вызовом (подумайте
DateTime.Now
). Определенно бывают моменты, когда имеет смысл применять это даже в бэкэнде класса.источник
Я использую их в сериализации, с такими вещами, как
DataContractSerializer
или protobuf-net, которые поддерживают это использование (XmlSerializer
не). Это полезно, если вам нужно упростить объект как часть сериализации:источник
Одна вещь, которую я делаю все время, это хранить "глобальные" переменные / кеш в
HttpContext.Current
источник
Я использую их время от времени. Они могут упростить отладку, когда вы можете легко установить точку останова в свойстве или добавить оператор ведения журнала и т. Д.
Также может быть полезно, если вам позже потребуется каким-то образом изменить тип ваших данных или если вам нужно использовать отражение.
источник
Я использую частные свойства, чтобы уменьшить код для доступа к под-свойствам, которые часто используются.
Это полезно, если есть много вложенных свойств.
источник
Обычной практикой является изменение членов с помощью методов get / set, даже закрытых. Теперь логика заключается в том, что вы знаете, что ваши get / set всегда ведут себя определенным образом (например, при запуске событий), что, кажется, не имеет смысла, поскольку они не будут включены в схему свойств ... но старые привычки тяжело умирают.
источник
Это имеет смысл, когда есть логика, связанная со свойством set или get (подумайте, ленивая инициализация), и свойство используется в нескольких местах в классе.
Если это просто прямое поле поддержки? Ничто не приходит на ум в качестве веской причины.
источник
Я знаю, что этот вопрос очень старый, но информации, приведенной ниже, не было ни в одном из текущих ответов.
Если вы вводите свои зависимости, вы, возможно, захотите иметь Getter для Property, а не setter, поскольку это будет означать свойство только для чтения. Другими словами, свойство может быть установлено только в конструкторе и не может быть изменено любым другим кодом в классе.
Кроме того, Visual Studio Professional будет предоставлять информацию о свойстве, а не поле, чтобы было легче увидеть, какое поле используется.
источник
Ну, как никто не упомянул, вы можете использовать его для проверки данных или для блокировки переменных.
Проверка
запирающий
Примечание. При блокировке ссылки вы не блокируете доступ к элементам ссылочного объекта.
Ленивая ссылка: При отложенной загрузке вам может понадобиться сделать это асинхронно, для чего в настоящее время существует AsyncLazy . Если вы пользуетесь более ранними версиями, чем Visual Studio SDK 2015, или не используете его, вы также можете использовать AsyncLazy от AsyncEx .
источник
Некоторые более экзотические использования явных полей включают в себя:
ref
илиout
со значением - возможно, потому что этоInterlocked
счетчикstruct
с явным макетом (возможно, для сопоставления с дампом C ++, илиunsafe
кодом)BinaryFormatter
автоматической обработкой полей (изменение на auto-props изменяет имена и, таким образом, разрушает сериализатор)источник