По какой причине люди используют свойства с get; набор; вместо полей?

Я часто вижу свойства в классах, а не в полях. Это выглядит так:

class TestClass
{
    public ulong Id { get; set; }
    public string Description { get; set; }
}

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
87
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

О, и это помогает при отладке: вы можете установить точку останова на «наборе», если хотите знать, кто меняет ваше значение (неожиданно).

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

Klaus Gütter 22.12.2020 15:26

@KlausGütter Это похоже на проблему курицы и яйца ... Если бы поля были основным способом программирования, привязка данных WPF поддерживала бы их. Когда вы используете отражение (как это делает привязка данных WPF), поиск свойства по имени или поля по имени представляет собой ту же сложность, и это то, что можно кэшировать, чтобы это не замедляло код.

xanatos 22.12.2020 15:42

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

user10608418 22.12.2020 15:54

TBH, если вы просто напишите { get; set; }, это ничего не инкапсулирует и работает так же, как поле. Также вы можете добавить { get; set; } к существующему полю и вместо этого иметь свойство без каких-либо проблем с обратной совместимостью.

Tomas Smagurauskas 22.12.2020 16:19

@TomasSmagurauskas: Не на 100% правда. Один сценарий, упомянутый OP, использует член в вызове метода, принимающего выходной параметр. Это редкий случай, но тот, который сломался бы здесь. Кроме того, соглашения об именах обычно этого не допускают. Поля используют другой регистр (и, как правило, префикс), чем свойства.

PMF 22.12.2020 16:38

Люди используют свойства вместо полей в основном из-за соглашений о кодировании. Если он не выполняет никакой фактической инкапсуляции (в случае POCO), то в C# нет большой разницы. В большинстве случаев поля можно использовать вместо свойств без каких-либо последствий.

// This:
public string MyValue;
// Could be later on changed to this:
public string MyValue { get; set; }
// With no compatibility issues.

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

Без проблем с совместимостью - неправда. Изменение поля на свойство является критическим изменением (код IL, добавляющий поле и свойство, сильно отличается, даже если исходный код C# выглядит одинаково). Любой клиент, использующий этот тип, как минимум должен быть перекомпилирован.

Klaus Gütter 23.12.2020 07:32

Другие вопросы по теме