0

I have read the Indexer docs and I know that indexer will be translate to generate a property named "Item". I want to inspect the generated code but I can't find the process function of compiler how to generate it. Source Code search of C#

  • Do you want to see the implementation? Or do you just want to know how to reference the `.Item` via reflection. It would help if you explained more on _Why_ you want to do this or how you will use the information. – Chris Schaller Jul 18 '21 at 13:19
  • @ChrisSchaller I want to see the implementation code. Thanks – five element god Jul 18 '21 at 13:25
  • I know that "Reflection" can iterate all property in an object. I am curious about how the compiler translate the "indexer" code to "Item" property. @ChrisSchaller – five element god Jul 18 '21 at 13:33
  • If you want to see how the compiler generates the indexer property, you might want to start with the CSharp compiler source rather than the .NET source. https://github.com/dotnet/roslyn – pmcoltrane Jul 18 '21 at 13:46

1 Answers1

1

In C#, property getters accept no parameters, and setters accept exactly one parameter only, so it is rather impossible for the compiler to generate a C# property (in the C# sense) for the indexer. If you expected to find C# code declaring a property called Item, you won't find that.

What the compiler does generate, is IL, and this is what the documentation meant - "property" in the IL sense. IL has indexed properties, and that's what indexers translate to. For example, an indexer like this:

public class Foo
{
    public string this[int index]
    {
        get => "";
        set {}
    }
}

translates to (play with this on SharpLab!):

.method public hidebysig specialname 
    instance string get_Item (
        int32 index
    ) cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 6 (0x6)
    .maxstack 8

    IL_0000: ldstr ""
    IL_0005: ret
} // end of method Foo::get_Item

.method public hidebysig specialname 
    instance void set_Item (
        int32 index,
        string 'value'
    ) cil managed 
{
    // Method begins at RVA 0x2057
    // Code size 2 (0x2)
    .maxstack 8

    IL_0000: nop
    IL_0001: ret
} // end of method Foo::set_Item

// Properties
.property instance string Item(
    int32 index
)
{
    .get instance string Foo::get_Item(int32)
    .set instance void Foo::set_Item(int32, string)
}

Notice that the Item property "takes a parameter". There is also a DefaultMemberAttribute added (not shown above).

Compare that last part with what normal C# properties translate to:

.property instance string Item()
{
    .get instance string Foo::get_Item()
    .set instance void Foo::set_Item(string)
}

Note that if you translate the IL code back to C#, you'll get the indexer back. Indexed properties don't exist in C#.

Sweeper
  • 213,210
  • 22
  • 193
  • 313