2014-12-18 6 views
1

차원에 관계없이 배열 인덱싱은 인덱서 연산자을 호출하기 때문에 메서드 호출입니다.1 차원 배열의 인덱싱 인스턴스가 MethodCallExpression이 아닌 BinaryExpression 인 이유는 무엇입니까?

그럼 왜있어서 System.Linq.Expressions.Expression.ArrayIndex의 과부하 takes a single array index는 인덱싱 다차원 배열을 표현하는하는 BinaryExpression 그 반면 other overloads을 반환하게된다 MethodCallExpression S를 반환하게된다?

이것은 대칭성을 깨기 때문에이 작은 변종을 기억하게 만듭니다. 그들이 그것을 MethodCallExpression으로 만들었다면 나는 기억하거나 아무것도 기억할 필요가 없었을 것입니다.

+1

IL에서 메서드 호출로 Hmm 배열 인덱서? 배열을 두 번 더 느리게 액세스하게 만들 것입니다. 그 이유는 없습니다. 1 차원 배열은 성능을 위해 조정됩니다. 다차원 배열은 그렇지 않습니다. –

+0

감사합니다. 나는 일리노이에 대해 교육받지 못했습니다. 해야 할 일 목록에있는 항목 중 하나입니다. –

답변

3

일리노이 주에있는 것처럼 보이기 때문입니다. CLI에는 "rank 1, 0 lower bound"배열 인 벡터 및 "any rank, any lower bound"배열 인 배열의 두 가지 종류가 있습니다. (예, 이름이 매우 혼란 스럽습니다.) 죄송합니다.

벡터는 런타임에보다 효율적인 산술 연산을 수행 할 수 있으므로 효율적입니다. 일리노이는 벡터 처리에 대한 구체적인 지침을 가지고 있지만 일반적인 배열 액세스는 방법을 거칩니다.

// 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 

따라서 식 트리가 그냥 : 같은 방법의 마지막 두 줄은 컴파일 -

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으로 보면 :

하면이 방법을 설명하기 위해이 코드를 컴파일 ldelem 명령어를 이진 연산자 (여기서 두 피연산자는 배열 및 인덱스 임)를 나타내는 반면 다차원 배열에 대한 메서드 호출을 사용합니다.

+0

고맙습니다. :-) –

+0

'vector'의 IL 세그먼트가'IL_0013 : ldloc.0' 명령을 포함하지 않아야합니까? – svick

+0

@svick : 아마도 :) 곧 수정 될 것입니다. –