2010-01-15 19 views
6

Aşağıdaki tür lambda ifadesi verildiğinde, aşağıdaki türde bir yerel özellik "bayt ÜlkeDeği" ve bir ortak özellik "bayt Kimliği" içeren Ülke türü bulunur.Lambda ifade derlemesi

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

İfade daha sonra NHibernate Linq sağlayıcısı tarafından kullanılır ve bir istisna attı. İfade değişkeni exp'i incelediğimde, eşitlik operatörünün her iki tarafının da Int32'ye dönüştürüldüğünü öğrendim. İki bayt değerleri için eşitlik operatörü önceden Int32 dönüştürülmesi bu değerler neden ihtiyaç

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

anlayamıyorum. Derleyicinin benim için yapmasına izin veren ifadeyi doğrudan yazdım. Aşağıdaki ifade, NHibernate Linq sağlayıcısı tarafından iyi bir şekilde dönüştürülür.

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 
    ); 

Bu nedenle, derleyicinin ifadeyi tür dönüşümü ile çıkarmasının bir nedeni olması gerekir. Herhangi bir fikir?

+0

Bir dil etiketine ihtiyacı var. –

cevap

6

Belirtime göre budur. §4.1.5 alıntı: sbyte, byte, short, ushort, int, uint, long, ulong ve char:

C# dokuz ayrılmaz türlerini destekler. [...]

tekli ve ikili operatörler hep imzalanmış 32 bitlik hassasiyetle faaliyet ayrılmaz tipi, işaretsiz 32 bit hassasiyet, 64 bit hassasiyet, ya işaretsiz 64 bit hassasiyet imzalı:

[ ...] için

ikili +, , *, /, %, &, ^, |, ==, !=, >, <, >= ve <= operatörleri, , işlenenler, T'nin, her iki işlenenin her türlü olası değerini tam olarak temsil edebilen int, uint, uzun ve ulong'un birinci olduğu T'ye dönüştürülür. İşlem daha sonra T tipi hassasiyet kullanılarak gerçekleştirilir ve sonucun tipi T (veya ilişkisel operatörler için bool) şeklindedir. Bir işlenenin uzun tipte olması ve diğerinin ikili operatörler ile ülung tipi olması yasaktır. == çağrılır önce

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

işlenenler b1 ve b2 için Böylece

, int terfi.

+5

Cevabınız için teşekkür ederiz. Bu, bayt türü değerlerini int32'ye dönüştürmenin derleyici davranışını açıklar. Ancak, yine de mantıklı değil. Lambda ifadesi derlenmiş bir temsilci değil, bir ifadeye dönüştürüldüğünden, hala C#, HQL vb. Dahil herhangi bir dilde tanımlanabilen bir ifade ağacı olmalıdır. Bu nedenle, herhangi bir dile özel uygulama içermemesi gerektiğini düşünüyorum.NHibernate Linq sağlayıcısı, üzerinde çalışmadan önce değişken türlerin tanıtımına ihtiyaç duymaz. Lambda ifadesi bir ifade ağacına dönüştürülmeden önce derlenmiş mi? –