Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding an automatic property

Tags:

c#

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?

like image 323
Thomas Avatar asked Aug 12 '13 08:08

Thomas


People also ask

How do you override a property?

An overriding property declaration must specify exactly the same access modifier, type, and name as the inherited property. Beginning with C# 9.0, read-only overriding properties support covariant return types. The overridden property must be virtual , abstract , or override .

What is an automatic property?

What is automatic property? Automatic property in C# is a property that has backing field generated by compiler. It saves developers from writing primitive getters and setters that just return value of backing field or assign to it.

What is property C#?

A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they're public data members, but they're special methods called accessors.

What is backing field in C#?

A private field that stores the data exposed by a public property is called a backing store or backing field. Fields typically store the data that must be accessible to more than one type method and must be stored for longer than the lifetime of any single method.


2 Answers

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

like image 27
Bob Vale Avatar answered Sep 19 '22 04:09

Bob Vale


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
like image 194
MarcinJuraszek Avatar answered Sep 20 '22 04:09

MarcinJuraszek