Анонимные вспомогательные поля все еще создаются для виртуальных автоматически реализуемых свойств, когда они переопределяются? - PullRequest
7 голосов
/ 21 июня 2011

болезненное любопытство. Скажем, у меня есть эта иерархия:

class Base {
  public virtual int Field { get; set; }
}

class Derived : Base {
  int _field;
  public override int Field { get { return _field; } set { _field = value; } }
}

Если я создаю экземпляр Base, компилятор волшебным образом создаст вспомогательное поле для свойства Field.

Итак, учитывая, что Derived не ссылается на базовую реализацию, создается ли вспомогательное поле при создании экземпляра Derived? Это продиктовано в спецификации C # или оставлено для реализации компилятора?

Обновление

Оказывается, что в спецификации действительно указано, что автоматически реализуемые свойства реализуются с помощью "скрытого" вспомогательное поле ". (Раздел 10.7.3) Ничего не сказано о моем конкретном вопросе. Предполагая, что слово" скрытый "относится к той же функции скрытия членов, которая предоставляется ключевым словом new, я должен заключить, что вспомогательное поле всегда создано независимо от использования.

Я предполагаю, что связанный вопрос может быть следующим: «Создано ли вспомогательное поле для автоматически реализуемого свойства, к которому никогда не осуществляется доступ?» Тот же основной аргумент, тот же вывод.

Ответы [ 3 ]

2 голосов
/ 21 июня 2011

Этот пример программы демонстрирует, что поле поддержки создано.Вызов GetFields возвращает вспомогательное поле Int32 <Field>k__BackingField в примере ниже.Вы можете установить и получить значение этого поля через отражение, но не через экземпляр derived.Вы также можете видеть, что сеттер, объявленный в классе Derived, не вызывается при обновлении поля с помощью отражения.

void Main()
{
    var derived = new Derived();
    derived.Field = 10;
    var fieldInfo = typeof(Base).GetFields(
                        BindingFlags.NonPublic | BindingFlags.Instance)[0];
    fieldInfo.SetValue(derived, 20);
    Console.WriteLine(derived.Field);
    Console.WriteLine(fieldInfo.GetValue(derived));
}

public class Base {
  public virtual int Field { get; set; }
}

public class Derived : Base {
  int _field;
  public override int Field 
  { 
      get { return _field; } 
      set { Console.WriteLine("Setter called."); _field = value; } 
  }
}

Вывод этой программы:

Setter called.
10
20

Значение 20, которое записывается вместе с экземпляром FieldInfo, возвращаемым из вызова к GetFields, показывает, что создано поле поддержки.

1 голос
/ 21 июня 2011

Итак, учитывая, что Derived не ссылается на базовую реализацию, создается ли вспомогательное поле при создании экземпляра Derived?

Абсолютно создается вспомогательное поле.Просто потому, что Derived не использует поле поддержки, предоставленное Base, для экземпляра от Derived до будет a Base, поле должно существовать.Представьте себе, если мы добавили следующий метод к Derived:

public int GetBaseField()
{
    return base.Field; // calls Base.get_Field(), which uses the base
                       // class's auto-generated backing property
}

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

0 голосов
/ 21 июня 2011

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

По той же причине, по которой частные методы, никогда не вызываемые в коде, все еще компилируются: C # Compilerоптимизация - Неиспользуемые методы

...