Override auto property

as it is

public int MyInt{ get; set;} 

equivalently

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

when creating an automatic virtual property

 public virtual int MyInt{ get; set;} 

and then override this property in the child class

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

Does this child class now have an inconvenient and hidden _myInt highlight?

+46
c #
Aug 12 '13 at 8:09
source share
4 answers

The short answer . Yes, Child selects all the fields of the Base class, so it still has a dedicated support field. However, you cannot access it otherwise than through the Base.MyInt property.

Long answer :

Quick disassembly results.

Base and Child implementation of classes:

 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 support field exists in the Base class. . However, it is private, so you cannot access it from the Child class:

 .field private int32 '<MyInt>k__BackingField' 

And your Child.MyInt property Child.MyInt not use this field. Property IL:

 .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 

Uses the anotherInt field, as you might expect.

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

  • Base.MyInt from class Child
+52
Aug 12 '13 at 8:21
source share
— -

This is not just equivalent to its actual implementation. The compiler overwrites your automatic properties at the precompilation stage. Although the field name will be called something else.

As a result, the behavior will be identical to how you create the property manually.

Yes, a hidden field will exist, but it will not be assigned because your redefinition does not invoke the underlying implementation.

if you changed the override to

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

Then the distribution will happen

+6
Aug 12 '13 at 8:16
source share

Yes, exactly as if it were not defined as an automatic property.

Distribution is necessary in the base class because it still needs to exist and be useful. The base class is unaware of the existence of the derived class, and the derived class can use the support field in its definition.

If you have a base and derived class defined as:

 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 base field of the base class really exists 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 support field is an undocumented implementation detail, so I will not use it in any production code. (I got it using LINQPad IL View)

+3
Aug 12 '13 at 8:14
source share

The MyInt field will be there, and it should be! The compiler cannot perform optimization based on subclass information. Consider, for example, that a derived class may not be present in a packaged running program.

updated since I misunderstood part of the question. Thanks @PVitt for pointing out.

+2
Aug 12 '13 at 8:27
source share



All Articles