Открытые поля против автоматических свойств

нам часто говорят, что мы должны защитить инкапсуляцию, сделав методы 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 показывает вам ссылки на свойство, но не поле.