为什么将一维数组索引为BinaryExpression而不是MethodCallExpression的实例?

时间:2014-12-18 10:58:58

标签: c# .net linq expression-trees linq-expressions

对数组建立索引,无论维度如何,都是方法调用,因为它涉及调用索引器运算符

那么为什么System.Linq.Expressions.Expression.ArrayIndex使takes a single array index方法的重载超过BinaryExpression,而其other overloads代表索引多维数组,返回MethodCallExpression s?

这打破了对称性,迫使我记住这个小异常。如果他们成为MethodCallExpression,我就不必记住或记下任何事情。

1 个答案:

答案 0 :(得分:3)

我怀疑它是因为它在IL中看起来像什么。 CLI有两种不同的数组:向量,它们是"排名1,0下界"数组和数组是"任何等级,任何下限"阵列。 (是的,命名很混乱。抱歉。)

向量更有效,因为运行时可以使用更简单的算法来访问它们。 IL具有处理向量的具体指令,但是一般的数组访问通过一种方法。

为了证明这一点,请编译以下代码:

class Test
{
    static void Main()
    {
        int[] vector = new int[10];
        int[,] array = new int[10, 10];
        int x = vector[0];
        int y = array[0, 0];
    }
}

然后用ildasm查看它 - 该方法的最后两行编译为:

// int x = vector[0]
IL_0013:  ldloc.0
IL_0014:  ldc.i4.0
IL_0015:  ldelem.i4
IL_0016:  stloc.2

// int y = array[0, 0]
IL_0017:  ldloc.1
IL_0018:  ldc.i4.0
IL_0019:  ldc.i4.0
IL_001a:  call       instance int32 int32[0...,0...]::Get(int32,
                                                          int32)
IL_001f:  stloc.3

因此表达式树只是将ldelem指令表示为二元运算符(其中两个操作数是预定的数组和索引),而它使用方法调用多维数组