2017-09-21 11 views
1

내 문제는 여기에서 C# 식 트리 (예 : System.Linq.Expressions)의 블록에 로컬 변수를 가져올 수 없어 함수 인수 변수가 완벽하게 작동 함에도 불구하고 예외를 throw하지 않고 작업 할 수 있습니다. 벌금.블록에 바인딩 된 C# 식 트리의 로컬 변수 선언

여기서 '로컬 변수'는 클로저를 의미하지 않습니다. 나는 C# 표현식 트리의 블록에 특별히 국한된 변수를 의미합니다. 현재, 나는 1 개 식 트리가 작동하는 매우 기괴한 사건을 가지고, 또 다른 예외가 발생합니다 :

처리되지 않은 'System.InvalidOperationException'형식의 예외가 System.Core.dll

추가 정보 발생을 형식 '선택 System.Int32'의 변수 'NUM은' ''범위에서 참조, 그러나에서 컴파일

근로 코드를 정의되지 않은 :

public static int Assign() 
{ 
    int num; 
    int num2; 
    num = 1; 
    num2 = 2; 
    return num + num2; 
} 
식 트리

(디버그 뷰) :이 정상적으로 작동

.Lambda #Lambda1<System.Func`1[System.Int32]>() { 
    .Block(
     System.Int32 $num, 
     System.Int32 $num2) { 
     0; 
     0; 
     $num = 1; 
     $num2 = 2; 
     .Return returnLabel { $num + $num2 }; 
     .Label 
      0 
     .LabelTarget returnLabel: 
    } 
} 

. 하지만, 내 컴파일러하려고 할 때이 컴파일 :

public static int Assign() 
{ 
    int num = 1; 
    int num2 = 2; 
    return num + num2; 
} 

같이

.Lambda #Lambda1<System.Func`1[System.Int32]>() { 
    .Block(
     System.Int32 $num, 
     System.Int32 $num2) { 
     $num = 1; 
     $num2 = 2; 
     .Return returnLabel { $num + $num2 }; 
     .Label 
      0 
     .LabelTarget returnLabel: 
    } 
} 

이 블록 표현은 잘못된 연산 예외가 발생합니다 -

유형의 처리되지 않은 예외 'System.InvalidOperationException를 'System.Core.dll에서 발생했습니다. 추가 정보 :'System.Int32 '형식의'num '변수가 범위에서 참조되었지만 정의되지 않았습니다.

01 23,516,
는 정말로 여기 혼란 것이 유일한 차이점은 임의 {0}에 의해 발생한다는 것입니다

- 사라 System.Linq.Expressions.Expression.Constant (0) 표현이 겉으로 만드는 오류 (이 존재하는 이유는

입니다

,895 : 식 트리를 출력

public static Crappier<int> FieldAssign(int i, Crap thing) 
     { 
      thing.field = i; 
      return new Crappier<int>(); ; 
     } 

미세 :

구체적으로,이 문제와 람다 식으로 정의 된 매개 변수, 예를 들면, 컴파일러 편 나타나지

그러나 구체적으로 한 블록에 바인딩 된 변수가 필요합니다. 내가 두 번 선언 있지만이 로컬 범위의에

for (int i = 0; i < 3; i++) { 
    Console.WriteLine("hello"); 
} 

for (int i = 0; i < 3; i++) { 
    Console.WriteLine("world"); 
} 

이 # 코드 C 유효가 선언되기 때문에 : 그 이유는 코드이다. 내 컴파일러는 다음을 컴파일하여 이것을 설명하려고합니다 :

*.Lambda #Lambda1<System.Action>() { 
    .Block() { 
     .Block(System.Int32 $i) { 
      $i = 0; 
      .Loop .LabelTarget forContinueLabel: { 
       .If ($i < 3) { 
        .Block() { 
         .Block() { 
          .Call System.Console.WriteLine("hello") 
         }; 
         $i++ 
        } 
       } .Else { 
        .Break forBreakLabel { } 
       } 
      } 
      .LabelTarget forBreakLabel: 
     }; 
     .Block(System.Int32 $i) { 
      $i = 0; 
      .Loop .LabelTarget forContinueLabel: { 
       .If ($i < 3) { 
        .Block() { 
         .Block() { 
          .Call System.Console.WriteLine("world") 
         }; 
         $i++ 
        } 
       } .Else { 
        .Break forBreakLabel { } 
       } 
      } 
      .LabelTarget forBreakLabel: 
     }; 
     .Label 
      3 
     .LabelTarget returnLabel: 
    } 
} 

이 문제를 해결하는 방법에 대한 제안이 있으십니까? 나는이 잘못된 지역 변수들을 완전히 잘못된 방향으로 다루고 있다는 것을 확신한다.

답변

0

Nevermind - 이것은 $ num 지정이 다른 객체를 참조했지만 블록의 매개 변수 표현식과 다른 이름 매개 변수 표현식을 참조하는 불쾌한 버그였습니다. 동일한 이름을 가진 매개 변수 표현식이 반드시 동일한 매개 변수 표현식 일 필요는 없습니다!