首页 > 解决方案 > 如何在 C# 中找到生成的“索引器”代码?

问题描述

我已经阅读了Indexer 文档,并且我知道 indexer 将被翻译以生成一个名为“Item”的属性。我想检查生成的代码,但找不到编译器的处理函数如何生成它。C#的源代码搜索

标签: c#indexer

解决方案


在 C# 中,属性 getter 不接受任何参数,而 setter 只接受一个参数,因此编译器几乎不可能为索引器生成C#属性(在 C# 意义上)。如果您希望找到声明名为 的属性的 C# 代码Item,您将找不到。

编译器生成的是 IL,这就是文档的意思——IL 意义上的“属性”。IL 具有索引属性,这就是索引器翻译的内容。例如,这样的索引器:

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

转换为(在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)
}

请注意,该Item属性“接受一个参数”。还有一个DefaultMemberAttribute添加(上面没有显示)。

将最后一部分与普通 C# 属性转换为的内容进行比较:

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

请注意,如果您将 IL 代码翻译回 C#,您将获得索引器。C# 中不存在索引属性。


推荐阅读