I'll start today's discussion with a question: do virtual properties exist and can you override them?
public class Base
{
public virtual int MyProperty { get { return 0; } }
}
public class Derived : Base
public override int MyProperty { get { return 42; } }
.property instance int32 MyProperty() { .get instance int32 Program.Base::get_MyProperty() } // end of property Base::MyProperty .property instance int32 MyProperty() { .get instance int32 Program.Derived::get_MyProperty() } // end of property Derived::MyProperty
.property instance int32 MyProperty()
.get instance int32 Program.Base::get_MyProperty()
} // end of property Base::MyProperty
.get instance int32 Program.Derived::get_MyProperty()
} // end of property Derived::MyProperty
Now where does it say virtual and override?
It turns out, unlike methods, properties cannot really "override" other properties. The property overriding we saw in the previous code sample is actually an syntatic artifact added by the C# compiler (and many others). Here is a excerpt from the CLI spec (ECMA 335), Partition I:
8.10.3 Property and event inheritance
Fundamentally, properties and events are constructs of the metadata intended for use by tools that target the
CLI and are not directly supported by the VES itself. Therefore, it is the job of the source language compiler
and the reflection library (see
source compiler shall generate CIL that directly accesses the methods named by the events and properties, not
the events or properties themselves.
Again using the previous C# code sample as an example, the real override is defined on the property getters, not the properties themselves:
.method public hidebysig newslot specialname virtual instance int32 get_MyProperty() cil managed { ... ... } // end of method Base::get_MyProperty .method public hidebysig specialname virtual instance int32 get_MyProperty() cil managed { ... ... } // end of method Derived::get_MyProperty
.method public hidebysig newslot specialname virtual
instance int32 get_MyProperty() cil managed
{ ... ... } // end of method Base::get_MyProperty
.method public hidebysig specialname virtual
{ ... ... } // end of method Derived::get_MyProperty
The fact that properties don't really override other properties have subtle impact on many Reflection APIs, some of which often catch users by surprise. I will talk about them in the next installments.
Note that Property is not the only member that has this fake inheritance. Event and sometimes Parameter have similar semantics.