2010-01-15 3 views
6

지방 유형에 "byte CountryId"공용 속성이 있고 "byte Id"공용 속성이 포함 된 국가 유형이있는 아래의 람다식이 제공됩니다.람다 표현식 컴파일

Expression<Func<Province, bool>> exp = p => p.CountryId == country.Id; 

표현식은 나중에 NHibernate Linq 공급자가 사용하고 예외를 던졌습니다. 표현식 변수 exp를 검사했을 때, 동등 연산자의 양쪽이 Int32로 변환된다는 것을 알았습니다.

{p => (Convert(p.CountryId) = Convert(value 
(AddressToGo.Business.Default.AddressComponents+<>c__DisplayClass0).country.Id))} 

2 바이트 값의 항등 연산자가 그 값을 Int32로 변환해야하는지 이해할 수 없습니다. 필자는 컴파일러가 나를 대신 할 수있는 식을 직접 작성했다. 다음 표현식은 NHibernate Linq 공급자에 의해 변환됩니다.

ParameterExpression prm = Expression.Parameter(typeof(Province), "p"); 
    Expression<Func<Province, bool>> exp = 
     Expression.Lambda<Func<Province, bool>> 
     (
     Expression.Equal 
     (
      Expression.MakeMemberAccess(prm, typeof(Province).GetProperty("CountryId")), 
      Expression.Constant(country.Id, typeof(byte)) 
     ), 
     prm 
    ); 

따라서 컴파일러가 형식 변환을 통해 표현식을 출력해야하는 이유가 있어야합니다. 어떤 아이디어?

+0

언어 태그가 필요합니다. –

답변

6

이것은 사양에 따른 것입니다. §4.1.5에서 인용 : sbyte, byte, short, ushort, int, uint, long, ulongchar :

번호 C는 적분 구 개 형태를 지원한다. [...]

단항 이진 연산자 항상 부호 32 비트 정밀도로 동작하는 일체형, 부호없는 32 비트 정밀도가 64 비트 정밀도 또는 부호없는 64 비트 정밀도 로그인 :

를 [ ...]의

이진 +, , *, /, %, &, ^, |, ==, !=, >, <, >=<= 연산자 피연산자는 형식 T로 변환됩니다. 여기서 T는 두 피연산자의 가능한 모든 값을 완전히 나타낼 수있는 int, uint, long 및 ulong 중 첫 번째 표현입니다. 그런 다음 연산은 유형 T의 정밀도를 사용하여 수행되며 결과의 유형은 T (또는 관계 연산자의 경우 bool)입니다. 하나의 피연산자는 long 타입이고 다른 하나는 이진 연산자와 함께 ulong 타입이 될 수 없습니다. == 호출 전에

byte b1; 
byte b2; 
bool b = (b1 == b2); 

피연산자 b1b2와 이에 대한

int로 승격된다.

+5

해답을 가져 주셔서 감사합니다. 바이트 형식 값을 int32로 변환하는 컴파일러 동작을 설명합니다. 그러나 아직 이해가되지 않습니다. 람다 표현식은 컴파일 된 델리게이트가 아닌 표현식으로 변환되기 때문에 나중에 C#, HQL 등을 포함한 모든 언어로 정의 할 수있는 표현식 트리 여야합니다. 따라서 언어 별 구현이 자유로 워야한다고 생각합니다.NHibernate Linq 프로 바이더는 변수 유형을 조작하기 전에이를 홍보 할 필요가 없습니다. 람다식이 표현식 트리로 변환되기 전에 컴파일 되었습니까? –