Открытые поля и автоматические свойства
Нам часто говорят, что мы должны защищать инкапсуляцию, создавая методы getter и setter (свойства в С#) для полей класса, вместо того, чтобы подвергать поля внешнему миру.
Но есть много раз, когда поле находится там, где нужно хранить значение и не требует каких-либо вычислений для получения или установки. Для этого мы все сделаем это число:
public class Book
{
private string _title;
public string Title
{
get{ return _title; }
set{ _title = value; }
}
}
Хорошо, у меня исповедь, я не мог писать все это (на самом деле, это не нужно было писать, нужно было смотреть на нее), поэтому я пошел изгоев и использовал публичные поля.
Затем идет С# 3.0, и я вижу, что они добавили автоматические свойства:
public class Book
{
public string Title {get; set;}
}
который является более аккуратным, и я благодарен за это, но на самом деле, что не так просто, как просто создание публичного поля?
public class Book
{
public string Title;
}
Ответы
Ответ 1
В связанном вопросе, который я имел некоторое время назад, была ссылка на публикацию в блоге Джеффа, объясняющую некоторые отличия.
Свойства против общедоступных переменных
Ответ 2
Игнорирование проблем API, то, что я считаю наиболее ценным в использовании свойства, - это отладка.
Отладчик CLR не поддерживает точки прерывания данных (большинство отладочных отладчиков). Следовательно, невозможно установить точку останова при чтении или записи определенного поля в классе. Это очень важно для некоторых сценариев отладки.
Поскольку свойства реализованы как очень тонкие методы, можно установить точки останова на чтение и запись их значений. Это дает им большую ногу над полями.
Ответ 3
Переход из поля в свойство нарушает контракт (например, требуется перекомпилировать весь ссылочный код). Поэтому, когда у вас есть точка взаимодействия с другими классами - любой публичный (и вообще защищенный) член, вы хотите планировать будущее развитие. Сделайте это, всегда используя свойства.
Это не значит, что сегодня это авто-свойство, и через 3 месяца вниз вы поймете, что хотите сделать его ленивым, и установите нулевую проверку в getter. Если вы использовали поле, это самое сложное перекомпиляция в лучшем случае и невозможное в худшем случае, в зависимости от того, кто и что еще полагается на ваши сборки.
Ответ 4
Просто потому, что никто не упомянул об этом: вы не можете определить поля на интерфейсах. Итак, если вам нужно реализовать определенный интерфейс, который определяет свойства, автоматические свойства иногда являются действительно приятной функцией.
Ответ 5
Огромная разница, которая часто упускается из виду и не упоминается ни в одном другом ответе: переопределение. Вы можете объявлять свойства виртуальными и переопределять их, тогда как вы не можете делать то же самое для полей публичных членов.
Ответ 6
Еще одно преимущество автоматически реализованных свойств над общедоступными полями заключается в том, что вы можете сделать закрытых или защищенных объектов доступа, предоставляя класс объектов, где он был определен лучше, чем обычный публичный.
Ответ 7
Все о стабильности версий и API. Нет никакой разницы в версии 1, но позже, если вы решите, что вам нужно сделать это свойство с некоторой проверкой ошибок в версии 2, вам не нужно менять API-интерфейс без изменений кода в любом месте, кроме определение свойства.
Ответ 8
Нет ничего плохого в создании поля public
. Но помните, что создание getter/setter
с private
не является инкапсуляцией. IMO, Если вам не нужны другие функции Property
, вы также можете сделать это public
.
Ответ 9
Если вы решите позже проверить, что заголовок уникален, сравнивая его с коллекцией или базой данных, вы можете сделать это в свойстве без изменения какого-либо кода, который зависит от него.
Если вы используете только публичный атрибут, тогда у вас будет меньше гибкости.
Дополнительная гибкость, не нарушая контракт, - это то, что наиболее важно для меня в отношении использования свойств, и, пока мне не нужна гибкость, авто-генерация имеет наибольший смысл.
Ответ 10
Одна вещь, которую я нахожу очень полезной, а также все причины кода и тестирования, заключается в том, что если это свойство и поле, то это означает, что среда Visual Studio IDE показывает вам ссылки на свойство, но не поле.
Ответ 11
Одним из аспектов является также производительность. Я обнаружил интересную вещь - в отладочной версии доступ к свойству почти удваивается медленнее (если не больше), чем в поле, НО в версии выпуска доступ к свойству незначительно быстрее, чем в поле!