Ответ 1
Он инкапсулирует генерируемое компилятором поле и предоставляет разработчику class
или struct
возможность обновлять его позже, не нарушая ваш API, просто изменяя часть get
/set
, о которой вы заботитесь.
Например, внезапно никогда не хочется возвращать null
? Вы можете сделать это, просто изменив пустой get
на get { return storedName ?? ""; }
. Конечно, это означает, что вам вдруг нужно вручную управлять переменной, но это небольшая цена, чтобы заплатить за гибкость.
Первое использование - это пример объявления . Второе использование - пример автоматически реализованного свойства.
Как правило, плохая практика обеспечивает прямой доступ к полю. Тем не менее, команда .NET заметила, что многие геттеры/сеттеры в основном такие. Например, рассмотрим следующее:
// C#
public string Name
{
get { return name; }
set { name = value; }
}
// Without properties (or a Java implementation)
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
В любом случае, это многословность, чтобы просто выставить поле. Тем не менее, регулярно, как разработчик, вам нужно вернуться и изменить, как поле обрабатывается внутренне, но вы не хотите разорвать или даже повлиять на другой код, если вы можете с ним справиться.
Вот почему использование прямого доступа к полям плохое. Если вы предоставляете прямой доступ к полям, но вам нужно что-то изменить об использовании этого поля, тогда также должен измениться весь код, который использует это поле. Если вы используете свойство (или даже метод), то вы можете изменить внутренний код и потенциально не влиять на внешний код.
Рассмотрим следующий пример:
public string Name
{
get;
set;
}
Позже вы решите, что вам нужно поднять измененное и измененное событие вокруг установщика. Если вы выставили поле, то это время для потенциально большой перезаписи. Если вы использовали свойства (или метод), то вы можете просто добавить туда логику. Вы внезапно потеряли преимущество авто-реализации свойств, но вы получили возможность реорганизовать свой класс, не нарушая существующий код.
private string name;
public event NameChangingEventHandler NameChanging;
public event NameChangedEventHandler NameChanged;
public string Name
{
get { return name; }
set
{
OnNameChanging(/*...*/);
name = value;
OnNameChanged(/*...*/);
}
}
protected virtual void OnNameChanging(/*...*/) { }
protected virtual void OnNameChanged(/*...*/) { }
Все это поддерживает ваш общедоступный API и не требует работы от пользователей этого класса (остальная часть вашего кода или внешних разработчиков, использующих ваш API). Нарушение изменений не всегда можно избежать, но избежать прямого доступа к полям - хороший шаг, чтобы попытаться убедиться, что этого не произойдет. Автоматически реализованные свойства - это быстрый и простой способ сделать это.
(Несвязанный: потерянная мощность при наборе текста, и я очень рад, что мой браузер сохранил большую часть этого!)