【问题标题】:Why is an instance of indexing a one-dimensional array a BinaryExpression and not a MethodCallExpression?为什么索引一维数组的实例是 BinaryExpression 而不是 MethodCallExpression?
【发布时间】:2014-12-18 10:58:58
【问题描述】:

索引数组,无论维度如何,都是一种方法调用,因为它涉及调用索引器操作符

那为什么方法System.Linq.Expressions.Expression.ArrayIndex的重载使得takes a single array index返回一个BinaryExpression,而它的表示索引多维数组的other overloads却返回MethodCallExpressions?

这只是打破了对称性,迫使我记住这个小异常。如果他们把它设为MethodCallExpression,我就不必记住或记下任何东西了。

【问题讨论】:

  • 嗯数组索引器作为 IL 中的方法调用?这会使数组访问速度变慢两倍,我认为没有理由。一维数组针对性能进行了调整。多维数组不是。
  • 谢谢。我对 IL 的了解并不多。这是我的待办事项之一。

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


【解决方案1】:

我怀疑这是因为这就是它在 IL 中的样子。 CLI 有两种不同的数组:vectors 是“rank 1, 0 lower bound”数组,arrays 是“any rank, any lower bound”数组。 (是的,命名很混乱。对不起。)

向量更高效,因为运行时可以通过更简单的算法来访问它们。 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 指令表示为二元运算符(其中两个操作数可能是数组和索引),而它使用的是多维数组的方法调用。

【讨论】:

  • 非常感谢。 :-)
  • vector 的 IL 段不应该包含IL_0013: ldloc.0 指令吗?
  • @svick:可能:) 会在一分钟内修复它。
猜你喜欢
  • 1970-01-01
  • 2020-07-14
  • 2019-01-31
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多