6 c# compiler-construction lambda byte equality
给定下面的lambda表达式,其中省类型包含公共属性"byte CountryId"和包含公共属性"byte Id"的Country类型.
Expression<Func<Province, bool>> exp = p => p.CountryId == country.Id;
Run Code Online (Sandbox Code Playgroud)
该表达式稍后由NHibernate Linq提供程序使用并引发异常.当我检查表达式变量exp时,我发现相等运算符的两边都转换为Int32.
{p => (Convert(p.CountryId) = Convert(value
(AddressToGo.Business.Default.AddressComponents+<>c__DisplayClass0).country.Id))}
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么两个字节值的相等运算符需要事先将这些值转换为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
);
Run Code Online (Sandbox Code Playgroud)
因此,编译器必须输出具有类型转换的表达式.有任何想法吗?
这符合规范.引自§4.1.5:
C#支持九种整数类型:
sbyte,byte,short,ushort,int,uint,long,ulong,和char.[...]积分型一元和二元运算符始终以带符号的32位精度,无符号32位精度,带符号的64位精度或无符号64位精度运行:
[...]
对于二元
+,–,*,/,%,&,^,|,==,!=,>,<,>=,和<=运营商,操作数被转换为类型T,其中T是int,UINT,长和ulong一个可以完全表示两者的所有可能值的操作数.然后使用类型T的精度执行操作,结果的类型是T(或关系运算符的bool).不允许一个操作数为long类型,另一个操作数为binary类型的二元运算符.
因此,为
byte b1;
byte b2;
bool b = (b1 == b2);
Run Code Online (Sandbox Code Playgroud)
调用操作数b1并b2在int之前被提升==.