2010-01-15 4 views
6

Étant donné l'expression lambda ci-dessous où Type de province contient une propriété publique "byte CountryId" et un type de pays qui contient une propriété publique "byte Id". L'expression est ensuite utilisée par le fournisseur NHibernate Linq et a déclenché une exception. Lorsque j'ai inspecté la variable d'expression exp, j'ai découvert que les deux côtés de l'opérateur d'égalité ont été convertis en Int32.Compilation d'expressions lambda

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

Je ne peux pas comprendre pourquoi l'opérateur d'égalité pour les deux valeurs d'octets besoin de ces valeurs pour être converties en Int32 au préalable. J'ai écrit l'expression directement sans laisser le compilateur le faire pour moi. L'expression suivante est convertie par le fournisseur NHibernate Linq. Donc, il doit y avoir une raison pour que le compilateur produise l'expression avec la conversion de type. Des idées?

+0

Nécessite un tag de langue. –

Répondre

6

Ceci est conforme à la spécification. Je cite §4.1.5:

C# prend en charge neuf types entiers: sbyte, byte, short, ushort, int, uint, long, ulong et char. [...]

Les opérateurs unaires et binaires de type intégré fonctionnent toujours avec précision signé 32 bits, non signé précision 32 bits, signé précision 64 bits, ou non signé précision 64 bits:

[ ...]

Pour le + binaire, , *, /, %, &, ^, |, ==, !=, >, <, >= et <=, les opérandes sont convertis en type T, où T est le premier de int, uint, long et ulong qui peut représenter complètement toutes les valeurs possibles des deux opérandes. L'opération est alors effectuée en utilisant la précision de type T, et le type de résultat est T (ou booléen pour les opérateurs relationnels). Il n'est pas permis à un opérande d'être de type long et l'autre d'être de type ulong avec les opérateurs binaires.

Ainsi, pour

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

les opérandes b1 et b2 sont promus à int avant == est invoquée.

+5

Merci pour la réponse. Cela explique le comportement du compilateur de convertir les valeurs de type octet en int32. Cependant, cela n'a toujours pas de sens. Puisque l'expression lambda est convertie en une expression, pas un délégué compilé, elle doit toujours être une arborescence d'expression qui peut être définie dans n'importe quel langage, y compris C#, HQL, etc. Je pense donc qu'elle doit être libre de toute implémentation spécifique.Le fournisseur de NHibernate Linq n'aurait pas besoin de la promotion des types de variables avant de les utiliser. L'expression lambda est-elle compilée avant d'être convertie en arbre d'expression? –