Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the magic that makes properties work with the CLR?

I noticed when I reflect into an assembly, calls to property accessors sometimes look like methods

// "Reflected" example
class Class1 {
   public bool Boolean { get; set;}
}

class Class2 {
   public Class2() {
       var class1 = new Class1();
       var boolean = class1.get_Boolean();
   }
}

Now I was curious, and I put a method with a similar signature in Class1 that looks like the standard convention for accessors.

// "Hacked" example
class Class1 {
   public bool get_Boolean() { return true; }
}

Somehow, the C# compiler still treats get_Boolean as a method.

What's the magic sauce to get a method to be a property?

like image 294
Daniel A. White Avatar asked Oct 26 '12 13:10

Daniel A. White


2 Answers

If you look at the IL, you'll find something like this:

.property instance string Source()
{
    .get instance string System.Exception::get_Source()
    .set instance void System.Exception::set_Source(string)
}

.method public hidebysig specialname newslot virtual 
    instance string get_Source () cil managed 
{
    ...
}

.method public hidebysig specialname newslot virtual 
    instance void set_Source (
        string 'value'
    ) cil managed 
{
    ...
}

So the 'magic' is a .property member which glues two methods together.

like image 174
dtb Avatar answered Nov 14 '22 10:11

dtb


A .NET assembly doesn't just contain code, it also contains metadata that describes the code.

In the case of a method, metadata is emitted that describes the method's name, signature, etc.

In the case of a property X, it is compiled as a bunch of accessor methods (get_X and/or set_X), and for each of these, the usual method metadata is emitted. Then, additional metadata is emitted, which specifies that all of these accessor methods actually belong together as one logical entity (the property).

Now, back to your example: If you define a method called get_Boolean using C#, the C# compiler will emit only the method metadata, but no additional property metadata. Essentially, the compiler gets to choose what metadata to emit. And since you didn't use the C# syntax for a property, but method declaration syntax, that's what the C# compiler will generate metadata for.

Metadata is described in detail in the ECMA 335 standard, which describes the CLI (.NET platform). Refer to chapter II.22.34 on page 241 for an explanation of how metadata for properties works.

like image 25
stakx - no longer contributing Avatar answered Nov 14 '22 10:11

stakx - no longer contributing