Открытые поля против автоматических свойств
нам часто говорят, что мы должны защитить инкапсуляцию, сделав методы getter и setter (свойства В C#) для полей класса, вместо того, чтобы подвергать поля внешнему миру.
но есть много раз, когда поле просто там, чтобы держать значение и не требует каких-либо вычислений, чтобы получить или установить. Для них мы все сделали бы это число:
public class Book
{
private string _title;
public string Title
{
get{ return _title; }
set{ _title = value; }
}
}
Ну, у меня есть признание, Я не мог вынести писать все это (на самом деле, это не нужно было писать, это было чтобы посмотреть на это), поэтому я пошел изгоем и использовал публичные поля.
затем приходит C# 3.0, и я вижу, что они добавили автоматические свойства:
public class Book
{
public string Title {get; set;}
}
который опрятнее, и я благодарен за это, но на самом деле, что так отличается от просто создания общественного поля?
public class Book
{
public string Title;
}
10 ответов
на вопрос некоторое время назад у меня была ссылка на сообщение в блоге Джеффа, объясняющее некоторые различия.
свойства против публичных переменных
- отражение работает по-разному на переменных и свойствах, поэтому, если вы полагаетесь на отражение, проще использовать все свойства.
- вы не можете привязать данные к переменной.
-
изменение переменной на свойство является разрывом изменение. Например:
TryGetTitle(out book.Title); // requires a variable
игнорируя проблемы API, то, что я считаю наиболее ценным в использовании свойства, - это отладка.
отладчик CLR не поддерживает точки останова данных (большинство отладчиков делать). Следовательно, невозможно установить точку останова для чтения или записи определенного поля в классе. Это очень ограничивает в некоторых сценариях отладки.
поскольку свойства реализованы как очень тонкие методы, можно установить точки останова на чтение и запись их ценности. Это дает им большую ногу над полями.
переход от поля к свойству нарушает контракт (например, требуется перекомпилировать весь ссылочный код). Поэтому, когда у вас есть точка взаимодействия с другими классами - любым публичным (и обычно защищенным) членом, вы хотите планировать будущий рост. Всегда используйте свойства.
Это ничего, чтобы сделать его автоматическим свойством сегодня, и через 3 месяца вы поймете, что хотите сделать его ленивым, и поместите нулевую проверку в геттер. Если вы использовали поле, это перекомпилировать изменения в лучшем случае и невозможно в худшем случае, в зависимости от того, кто и что еще полагается на ваши сборки.
просто потому, что никто не упомянул об этом: вы не можете определить поля на интерфейсах. Таким образом, если вам нужно реализовать определенный интерфейс, который определяет свойства, auto-properties иногда очень приятная функция.
огромная разница, которая часто упускается из виду и не упоминается ни в одном другом ответе:переопределение. Можно объявить свойства виртуальными и переопределить их, но нельзя сделать то же самое для открытых полей-членов.
еще одним преимуществом автоматически реализованных свойств над общедоступными полями является то, что вы можете сделать set accessors закрытыми или защищенными, предоставляя класс объектов, где он был определен, лучше, чем у общедоступных полей.
все дело в управлении версиями и стабильности API. В версии 1 нет никакой разницы, но позже, если вы решите, что вам нужно сделать это свойство с некоторым типом проверки ошибок в версии 2, вам не нужно менять свой API - код не изменяется нигде, кроме определения свойства.
нет ничего плохого в поле public
. Но помните о создании getter/setter
С private
поля-это не инкапсуляция. ИМО, если вы не заботитесь о других функциях Property
, вы могли бы также сделать это public
.
Если вы решите позже проверить, что заголовок уникален, сравнивая с коллекцией или базой данных, вы можете сделать это в свойстве без изменения кода, который зависит от него.
Если вы идете только с публичным атрибутом, то у вас будет меньше гибкости.
дополнительная гибкость без нарушения контракта-это то, что наиболее важно для меня в использовании свойств, и, пока мне действительно не понадобится гибкость, автогенерация имеет наибольший смысл.
одна вещь, которую я нахожу очень полезной, а также все причины кода и тестирования заключается в том, что если это свойство против поля, то Visual Studio IDE показывает вам ссылки на свойство, но не поле.