Отменяет ли автоматически реализованные свойства использование полей? - PullRequest
0 голосов
/ 19 декабря 2011

Поскольку свойства могут иметь открытые и закрытые методы получения / установки, все еще используется поле?Любое поведение, которое вы получаете от использования полей, можно получить, разработав блоки свойств get / set для использования невидимой переменной, которую использует компилятор, и полностью исключив поля?

Ответы [ 5 ]

3 голосов
/ 19 декабря 2011

нет, автоматически реализуемые реквизиты НЕ устраняют необходимость в вспомогательных полях. Иногда свойство getter / setter выполняет больше работы, чем просто удерживает значение. Есть много случаев, когда вы можете захотеть поле. очень хороший пример - реализация INotifyPropertyChanged для привязки.

вроде так:

class someClass : INotifyPropertyChanged
{
// details omitted.....

    private int _myInt
    public int myInt { get { return _myInt; }
                       set { if ( value == _myInt ) return;
                             _myInt = value;
                             RaiseNotify("myIng");
                           }}
}

это было бы невозможно без резервных полей.

0 голосов
/ 19 декабря 2011

Хотя можно получить значение поля и установить поле, поля позволяют сделать пару вещей, которые нельзя сделать со свойствами:

  1. Можно изменить значение поля таким образом, чтобы новое значение зависело от старого значения в точный момент изменения. Эта семантика отличается от чтения свойства, вычисления нового значения и его обратной записи.
  2. Можно передать поле посредством ссылки на методы, которые затем могут свободно выполнять любую последовательность операций чтения и записи, которую они считают нужными, при этом такие операции чтения или записи происходят "вживую". Опять же, это имеет другую семантику от передачи копии свойства методу, получения модифицированной копии обратно от метода и сохранения этой измененной копии обратно в оригинал.

Если бы кто-то хотел выставить свойство таким образом, чтобы можно было делать с ним «похожие на поля» вещи, но без экспонирования фактического поля можно было бы иметь семейство общих методов UseProperty, объявленных как:

delegate TResult; FuncRef<T1, TResult>(ref T1);
ResultType UseProperty<ResultType>
  (FuncRef func)
  {return func(_field);}
delegate TResult; FuncRef(ref T1 p1, ref T2 p2>
ResultType UseProperty<ResultType, T1>
  (FuncRef<propertyType, T1, ResultType> func, ref T1 p1)
  {return func(_field, p1);}
delegate TResult; FuncRef(ref T1 p2, ref T2 p2, ref T3 p3>
ResultType UseProperty<ResultType, T1, T2>
  (FuncRef<propertyType, T1, T2, ResultType> func, ref T1 p1, ref T2 p2)
  {return func(_field, p1, p2);}

К сожалению, нет хорошего способа объявить семейство таких функций в C # или vb (то есть «универсальная» функция, которая будет принимать любое количество параметров «ref» и делать их доступными для вызываемого кода). Слишком плохо, поскольку в противном случае при некоторой языковой поддержке такой подход мог бы обеспечить очень хорошую парадигму для контроля доступа к информации (то есть он мог подготовиться к изменению определенной информации, позволить общему коду изменять информацию, а затем воздействовать на измененную информацию). информация, без необходимости создания каких-либо новых экземпляров объекта).

0 голосов
/ 19 декабря 2011

В большинстве случаев вы можете использовать геттеры и сеттеры автогена вместо поля, но есть небольшая разница: геттер и сеттер являются вызовом функции, даже если они встроены - таким образом, переменная-резерв всегда указывается так, как если бы она были летучими.

0 голосов
/ 19 декабря 2011

Автоматически реализованные свойства устраняют необходимость в полях в простых случаях.

Однако, если вы хотите добавить какую-либо логику, проверку или события в установщик свойств, вам все равно потребуется поле.

0 голосов
/ 19 декабря 2011

Основная причина, по которой люди используют свойства для защищенных и открытых полей, заключается в том, что вы можете добавить поведение, не нарушая двоичную совместимость.Это означает, что код, использующий (вызовы, подклассы и т. Д.) Ваш класс, не нуждается в перекомпиляции.

Нет реальной необходимости использовать свойства для закрытых членов без какого-либо поведения.В этом случае вы можете использовать поле.Если вам позже потребуется добавить поведение (сделав его свойством), вы все равно будете перекомпилировать этот класс.

Поля работают лучше (хотя это зависит от того, какая у вас версия JIT), поэтому они должны бытьиспользуется, если нет причины.

РЕДАКТИРОВАТЬ:

Просто, чтобы избежать путаницы:

Поле:

private SomeType fieldName;

Авто-свойство:

private SomeType fieldName { get; set; }
...