Нам часто говорят, что мы должны защищать инкапсуляцию, создавая методы 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;
}
c#
class
properties
field
automatic-properties
IJ Кеннеди
источник
источник
prop
Фрагмент кода позволяет быстро создавать свойства. Просто введитеprop
вкладку.Ответы:
В связанном вопросе, который у меня был некоторое время назад, была ссылка на пост в блоге Джеффа, объясняющий некоторые различия.
Свойства против публичных переменных
Изменение переменной на свойство является критическим изменением. Например:
источник
ref
илиout
ключевому слову), а свойство является парой методов доступа и не может быть передано по ссылке. Например,bool success = TryGetMyTitle(out myBook.Title);
который использует,out
будет работать с полем, а не работать со свойством. Это четкий пример того, почему переход от поля к свойству является серьезным изменением!ref
/out
, а затем установить для свойства значение, которое имеет локальная переменная. Но тогда вызываемый метод сам по себе не обращается к свойству, он обращается к локальной переменной, которую вы там сделали.public int Foo { get; }
что создаст авто-свойство с полем только для чтения.Игнорирование проблем с API, вещь, которую я считаю наиболее ценной при использовании свойства, это отладка.
Отладчик CLR не поддерживает точки разрыва данных (большинство нативных отладчиков поддерживают). Следовательно, невозможно установить точку останова для чтения или записи определенного поля в классе. Это очень ограничивает в некоторых сценариях отладки.
Поскольку свойства реализованы в виде очень тонких методов, можно установить точки останова при чтении и записи их значений. Это дает им большую ногу над полями.
источник
Переход от поля к свойству нарушает контракт (например, требует перекомпиляции всего ссылочного кода). Поэтому, когда у вас есть точка взаимодействия с другими классами - любым публичным (и обычно защищенным) членом, вы хотите планировать дальнейший рост. Делайте так, всегда используя свойства.
Ничто не делает его авто-свойством сегодня, и через 3 месяца понимают, что вы хотите сделать его лениво загруженным, и поставьте нулевую проверку в геттере. Если вы использовали поле, в лучшем случае это перекомпилированное изменение, а в худшем - невозможно, в зависимости от того, кто и что еще полагается на ваши сборки.
источник
Просто потому, что никто не упомянул об этом: вы не можете определять поля на интерфейсах. Таким образом, если вам нужно реализовать определенный интерфейс, который определяет свойства, то авто-свойства иногда очень полезны.
источник
Огромная разница, которая часто упускается из виду и не упоминается ни в одном другом ответе: переопределение . Вы можете объявить свойства виртуальными и переопределить их, тогда как вы не можете сделать то же самое для открытых полей членов.
источник
Все дело в управлении версиями и стабильности API. В версии 1 нет никакой разницы - но позже, если вы решите, что вам нужно сделать это свойство с определенным типом проверки ошибок в версии 2, вам не нужно менять свой API - никаких изменений кода нигде, кроме определение свойства.
источник
Другое преимущество автоматически реализуемых свойств над открытыми полями состоит в том, что вы можете сделать наборы доступа частными или защищенными, предоставляя классу объектов, для которых было определено, лучший контроль, чем для открытых полей.
источник
Нет ничего плохого в создании поля
public
. Но помните, что созданиеgetter/setter
сprivate
полями - это не инкапсуляция. ИМО, если вам не нужны другие функцииProperty
, вы можете сделать этоpublic
.источник
Если позднее вы решите проверить, является ли заголовок уникальным, по сравнению с коллекцией или базой данных, вы можете сделать это в свойстве без изменения какого-либо кода, который зависит от него.
Если вы используете только публичный атрибут, у вас будет меньше гибкости.
Для меня наиболее важна дополнительная гибкость без нарушения контракта, и до тех пор, пока мне действительно не понадобится гибкость, автогенерация имеет смысл.
источник
Одна вещь, которую я нахожу очень полезной, так же как и весь код и причины тестирования, состоит в том, что, если это свойство по сравнению с полем, то в среде IDE Visual Studio отображаются ссылки на свойство, а не поле.
источник
Мой POV после некоторых исследований
Это действительно дает нам больше возможностей и расширяемости.
источник