是否可以从自己的getter中的数组类型属性获取索引

时间:2018-09-12 10:41:51

标签: c# properties getter

如果我有数组属性

private byte[] myProperty;

public byte[] MyProperty
{
    get { return myProperty; }
    set { myProperty= value; }
}

我可以叫它

MyProperty[3]

我想在getter中获得索引值3。 是否可以像这样从自己的getter中的数组类型属性获取索引

public byte[] MyProperty[int index]
{
    get 
    {
        return MyMethod(index);
    }
}

不使用您自己的类型,例如question,并且不将属性更改为此类方法

public byte[] MyPropertyMethod(int index) => MyMethod(index);

1 个答案:

答案 0 :(得分:2)

您有限制地描述

  

不使用您自己的类型并且不更改方法的属性

这是不可能的(使用C#语言功能)。

C#语句

byte i = MyProperty[3];

被编译为以下IL:

IL_001f: ldloc.0
IL_0020: callvirt instance uint8[] ConsoleApp1.Cls::get_MyProperty()
IL_0025: ldc.i4.3
IL_0026: ldelem.u1

您看到对属性getter get_MyProperty(在偏移IL_0020处)的调用发生在甚至不知道项目索引之前。仅在偏移量IL_0025处,代码知道索引3中的数组元素需要从数组中加载。那时,getter方法已经返回,因此您没有机会在该方法内部的任何地方获取该索引值。

您唯一的选择是进行低级IL代码修补。您将需要使用第三方工具甚至手动“破解”已编译的IL代码,但强烈建议不要使用这两种工具。

您需要将对getter方法的调用替换为对您的MyMethod的直接调用:

IL_001f: ldloc.0   // unchanged
                   // method call at IL_0020 removed
         ldc.i4.3  // instead, we first copy the index value from what was previously at IL_0025...
         callvirt instance uint8[] ConsoleApp1.Cls::MyMethod(int32) // ...and then call our own method
         ldc.i4.3  // the rest is unchanged
         ldelem.u1