Я часто вижу свойства в классах, а не в полях. Это выглядит так:
class TestClass
{
public ulong Id { get; set; }
public string Description { get; set; }
}
Почему народы это делают? Вместо этого они могут использовать поля. Я вижу там как минимум один плюс — мы можем передавать поля с ключевым словом ref
в функции. Есть ли какие-либо преимущества для свойств или другие причины, чтобы использовать их таким образом?
Основная причина заключается в инкапсуляции — значение можно изменить только через соответствующие свойства, и это остается в силе, даже если позже вы решите, что свойство не должно просто возвращать значение. Может быть, вы обнаружите, что хотите запускать событие при изменении значения? Если у вас есть недвижимость, это очень просто. Если у вас есть общедоступное поле, вам нужно внести критическое изменение.
Кроме того, свойства могут быть виртуальными или объявленными в интерфейсах. И их можно объявить доступными только для чтения.
О, и это помогает при отладке: вы можете установить точку останова на «наборе», если хотите знать, кто меняет ваше значение (неожиданно).
@KlausGütter Это похоже на проблему курицы и яйца ... Если бы поля были основным способом программирования, привязка данных WPF поддерживала бы их. Когда вы используете отражение (как это делает привязка данных WPF), поиск свойства по имени или поля по имени представляет собой ту же сложность, и это то, что можно кэшировать, чтобы это не замедляло код.
@xanatos Я не согласен, что wpf - это проблема курицы и яйца. Если вы хотите получать обновления для своих привязок данных, вам нужно создать событие, и это как раз один из сценариев, упомянутых в этом ответе, где вам нужно свойство. Возможно, они могли бы также поддерживать поля для случаев, когда люди уверены, что значения никогда не меняются, или они не хотят, чтобы пользовательский интерфейс отражал изменения, но я понимаю, почему они решили поддерживать только свойства, которые работают в любом случае, так что сделайте много. более гибкий код wpf.
TBH, если вы просто напишите { get; set; }
, это ничего не инкапсулирует и работает так же, как поле. Также вы можете добавить { get; set; }
к существующему полю и вместо этого иметь свойство без каких-либо проблем с обратной совместимостью.
@TomasSmagurauskas: Не на 100% правда. Один сценарий, упомянутый OP, использует член в вызове метода, принимающего выходной параметр. Это редкий случай, но тот, который сломался бы здесь. Кроме того, соглашения об именах обычно этого не допускают. Поля используют другой регистр (и, как правило, префикс), чем свойства.
Люди используют свойства вместо полей в основном из-за соглашений о кодировании. Если он не выполняет никакой фактической инкапсуляции (в случае 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# выглядит одинаково). Любой клиент, использующий этот тип, как минимум должен быть перекомпилирован.
Есть также некоторые обычаи, строго требующие свойств, например. Привязка данных WPF.