C # 3.0 Автоматические свойства, почему бы не получить доступ к полю напрямую? - PullRequest
12 голосов
/ 06 октября 2008

С новым подходом получения / установки в атрибуте класса:

public string FirstName {
        get; set;
    }

Почему бы просто не поставить атрибут FirstName public без аксессора?

Ответы [ 9 ]

30 голосов
/ 06 октября 2008

Две большие проблемы с прямым доступом к переменной внутри класса (поле / атрибут):

1) Вы не можете легко привязать данные к полям.

2) Если вы открываете открытые поля из своих классов, вы не можете позже изменить их на свойства (например: добавить логику проверки в установщики)

14 голосов
/ 06 октября 2008

Потому что в будущем, если вы измените реализацию, код, использующий текущий интерфейс, не сломается.

Например, вы реализуете простой класс с открытым полем и начинаете использовать ваш класс в некоторых внешних модулях. Месяц спустя вы обнаружите, что вам нужно реализовать отложенную загрузку в этом классе. Затем вам нужно будет преобразовать поле в свойство. С точки зрения внешнего модуля, он может выглядеть одинаково синтаксически, но это не так. Свойство - это набор функций, а поле - это смещение в экземпляре класса.

Используя свойство, вы эффективно снижаете риск изменения интерфейса.

3 голосов
/ 06 октября 2008

Это в основном сводится к тому, что он стал общим соглашением о кодировании. Это позволяет легко добавить пользовательский код обработки, если вы хотите. Но вы правы, технически в этом нет реальной необходимости. Хотя, если вы добавите пользовательскую обработку позже, это поможет вам не нарушать интерфейс.

2 голосов
/ 16 октября 2008

Этот стиль записи более полезен, когда вы смешиваете доступность для геттера и сеттера. Например, вы можете написать:

public int Foo { get; private set; }

Вы также можете установить внутренний установщик или даже сделать его частным, а установщик общедоступным.

Эта нотация исключает необходимость явной записи закрытой переменной только для решения классической проблемы значения, доступного для записи / чтения изнутри.

1 голос
/ 06 октября 2008

Ключ в том, что компилятор преобразует свойство «под капотом» в пару функций, а когда у вас есть код, который выглядит так, как будто он использует свойство, он фактически вызывает функции при компиляции в IL.

Итак, допустим, вы построили это как поле и имеете код в отдельной сборке, которая использует это поле. Если позже реализация изменится и вы решите сделать это свойством скрывать изменения от остальной части вашего кода, вам все равно придется перекомпилировать и повторно развернуть другую сборку. Если это свойство с самого начала, то все будет просто работать.

0 голосов
/ 16 октября 2008

Сохраняет инкапсуляцию объекта и сокращает код, чтобы его было проще читать.

0 голосов
/ 15 октября 2008

Когда вы получаете сообщение об ошибке и вам необходимо выяснить, какие методы изменяют ваши поля и когда, вам будет гораздо важнее. Если поместить легкие аксессоры свойств впереди, это сэкономит феноменальное количество душевной боли, если возникнет ошибка, связанная с областью, которую вы завернули. Я был в такой ситуации пару раз, и это не очень приятно, особенно когда это связано с повторным входом.

Выполнение этой работы заранее и установка точки останова на метод доступа намного проще, чем альтернативы.

0 голосов
/ 15 октября 2008

В 99% случаев открытое открытое поле вполне подходит.

Обычный совет - использовать поля: «Если вы открываете открытые поля из ваших классов, вы не сможете позже изменить их на свойства». Я знаю, что мы все хотим, чтобы наш код был ориентирован на будущее, но есть некоторые проблемы с этим мышлением:

  • Потребители вашего класса могут перекомпилировать, когда вы измените интерфейс.

  • 99% ваших членов данных никогда не станут нетривиальными свойствами. Это спекулятивная общность . Вы пишете много кода, который, вероятно, никогда не будет полезен.

  • Если вам нужна двоичная совместимость между версиями, возможно, недостаточно добавить элементы данных в свойства. По крайней мере, вы должны только выставлять interfacess и скрывать все конструкторы, и выставлять фабрики (см. Код ниже).


public class MyClass : IMyClass
{
    public static IMyClass New(...)
    {
        return new MyClass(...);
    }
}

Это трудная проблема, пытаться создать код, который будет работать в неопределенном будущем. Действительно тяжело.

У кого-нибудь есть пример, когда при использовании тривиальных свойств сохранял свой бекон?

0 голосов
/ 06 октября 2008

Я думаю, что спрашивающий спрашивает, почему бы не сделать следующее ...

public string FirstName { }

Зачем беспокоиться о аксессуарах, если вы можете сократить его до вышеуказанного. Я думаю, что ответ заключается в том, что требование доступа делает очевидным для человека, читающего код, что это стандартное получение / установка. Без них, как вы можете видеть выше, трудно заметить, что это автоматически реализуется.

...