Lambda expression compilation
Given the lambda expression below where Province type contains a public property "byte CountryId" and Country type which contains a public property "byte Id".
Expression<Func<Province, bool>> exp = p => p.CountryId == country.Id;
The Expression is later used by NHibernate Linq provider and threw an exception. When I inspected the expression variable exp, I found out that both sides of the equality operator were converted to Int32.
{p => (Convert(p.CountryId) = Convert(value
(AddressToGo.Business.Default.AddressComponents+<>c__DisplayClass0).country.Id))}
I can't understand why the equality operator for two b开发者_开发百科yte values need those values to be converted to Int32 beforehand. I have written the expression directly wihout letting the compiler do it for me. The following expression is converted by NHibernate Linq provider just fine.
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
);
So, there must be a reason why the compiler outputs the expression with type conversion. Any ideas?
This is per the specification. Quoting from §4.1.5:
C# supports nine integral types:
sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
, andchar
. [...]The integral-type unary and binary operators always operate with signed 32-bit precision, unsigned 32-bit precision, signed 64-bit precision, or unsigned 64-bit precision:
[...]
For the binary
+
,–
,*
,/
,%
,&
,^
,|
,==
,!=
,>
,<
,>=
, and<=
operators, the operands are converted to type T, where T is the first of int, uint, long, and ulong that can fully represent all possible values of both operands. The operation is then performed using the precision of type T, and the type of the result is T (or bool for the relational operators). It is not permitted for one operand to be of type long and the other to be of type ulong with the binary operators.
Thus, for
byte b1;
byte b2;
bool b = (b1 == b2);
the operands b1
and b2
are promoted to int
before ==
is invoked.
精彩评论