Открытые поля и автоматические свойства
нам часто говорят, что мы должны защищать инкапсуляцию, создавая методы 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 месяца вы поймете, что хотите сделать его ленивым, и поместите нулевую проверку в геттер. Если вы использовали поле, это перекомпилировать изменения в лучшем случае и невозможно в худшем случае, в зависимости от того, кто и что еще зависит от ваших сборок.
просто потому, что никто не упоминал об этом: вы не можете определить поля на интерфейсах. Итак, если вам нужно реализовать определенный интерфейс, который определяет свойства, авто-свойства иногда являются действительно хорошей функцией.
огромная разница, которая часто упускается из виду и не упоминается ни в одном другом ответе: переопределение. Вы можете объявить свойства виртуальными и переопределить их, в то время как вы не можете сделать то же самое для открытых полей-членов.
еще одно преимущество автоматически реализованных свойств над общедоступными полями заключается в том, что вы можете сделать набор методов доступа закрытым или защищенным, обеспечивая класс объектов, где он был определен, лучшим контролем, чем у общедоступных полей.
Это все о версии и стабильности API. В версии 1 нет никакой разницы, но позже, если вы решите, что вам нужно сделать это свойство с некоторым типом проверки ошибок в версии 2, вам не нужно менять свой API - никаких изменений кода, нигде, кроме определения свойства.
нет ничего плохого в поле
public
. Но помните о созданииgetter/setter
Сprivate
поля-это не инкапсуляция. ИМО, если вы не заботитесь о других особенностяхProperty
, вы могли бы также сделать этоpublic
.
Если вы решите позже проверить, что заголовок уникален, сравнивая его с коллекцией или базой данных, вы можете сделать это в свойстве, не изменяя код, который зависит от него.
Если вы идете только с публичным атрибутом, то у вас будет меньше гибкости.
дополнительная гибкость без нарушения контракта-это то, что наиболее важно для меня в использовании свойств, и, пока мне действительно не нужна гибкость, автогенерация имеет наибольший смысл.