Overriding an automatic property

since this

public int MyInt{ get; set;}

is equivalent to

private int _myInt;
public int MyInt{ get{return _myInt;} set{_myInt = value;} }

when you make the automatic property virtual

public virtual int MyInt{ get; set;}

and then override this property in a child class

public override int MyInt{ get{return someVar;} set{someVar = value;} }

does this child class now have an unwelcomed and hidden allocation of _myInt?


Short Answer: Yes, the Child allocates all Base class fields, so it still has the backing field allocated. However, you can't access it any other way than through Base.MyInt property.

Long Answer:

Quick disassembly results.

Base and Child classes implementation:

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

public class Child : Base
{
    private int anotherInt;

    public override int MyInt
    {
        get { return anotherInt; }
        set { anotherInt = value; }
    }
}

enter image description here

As you can see, the backing field exists within Base class. However, it is private, so you can't access it from Child class:

.field private int32 '<MyInt>k__BackingField'

And your Child.MyInt property does not use that field. The property IL is:

.method public hidebysig specialname virtual 
    instance int32 get_MyInt () cil managed 
{
    // Method begins at RVA 0x2109
    // Code size 7 (0x7)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldfld int32 ConsoleApplication2.Child::anotherInt
    IL_0006: ret
} // end of method Child::get_MyInt

.method public hidebysig specialname virtual 
    instance void set_MyInt (
        int32 'value'
    ) cil managed 
{
    // Method begins at RVA 0x2111
    // Code size 8 (0x8)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldarg.1
    IL_0002: stfld int32 ConsoleApplication2.Child::anotherInt
    IL_0007: ret
} // end of method Child::set_MyInt

Is uses anotherInt field, as you could expect.

The only ways to access the '<MyInt>k__BackingField' (indirectly, through Base.MyInt property) are:

  • base.MyInt from within Child class

It's not just equivalent its pretty much the actual implementation. The compiler rewrites your automatic properties in its precompile stage. Albeit the field name will be named something else.

As a result the behaviour will be identical to you creating the property manually.

Yes the hidden field will exist, however it will not be assigned to because your override doesn't call the base implementation.

if you changed the override to

public override int MyInt
{
  get { return someVar; }
  set { 
    someVar = value;
    base.MyInt = value
  }
}

Then the allocation would occur


Yes, just as if it was not defined as an automatic property.

The allocation is needed in the base class, because it still needs to exist and be useful. The base class has no knowledge of the existence of the derived class, and the derived class can use the backing field in its definition

If you have a base and derived class defined like:

public class Base
{
  public virtual string Name {get; set;}
}

public class Derived : Base
{
  private string _name;

  public override string Name 
  {
    get { 
      return _name; 
    }
    set 
    { 
      //access the base property we are overriding
      base.Name = value + " from derived";
      _name = value;
    }
  }
}

You can use reflection to see that the backing field of the base class does indeed exist, and behaves as expected:

Type tbase = typeof(Base);
FieldInfo fi = tbase.GetField("<Name>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance);

Base b = new Base {Name = "Test"};

string baseValue = fi.GetValue(b).ToString();
Console.WriteLine(baseValue); //gives "Test";

Derived d = new Derived {Name = "Test" };

string derivedValue = fi.GetValue(d).ToString();
Console.WriteLine(derivedValue); //gives "Test from derived";

The name of the actual backing field is an undocumented implementation detail, so I wouldn't use it in any production code. (I got it by using LINQPad's IL View)