6
votes

Cast implicite ne se produit pas dans l'arbre d'expression

J'ai rencontré un scénario où je dois trier une liste de type personnalisée sur différentes propriétés en fonction de l'entrée. Avec l'aide de quelques articles, j'ai pu proposer une implémentation générique à l'aide de tests unitaires Linq.During, l'un des tests échoués car la conversion implicite se produisait lorsque l'expression Lamda a été créée à l'aide de l'arborescence d'expression.

ci-dessous j'ai mis le exemple de code pour comprendre le problème (pas sûr pourquoi le formatage n'était pas correct, désolé pour cela) xxx

dans la méthode principale, lorsque j'essaie de transmettre un délégué de fonctionnement de Func directement à Trier la méthode de l'extension, il fonctionne, mais il échoue avec l'arborescence d'expression.

J'ai trouvé un Similaire problème, mais cela parle de paramètres de type contraint. Est-ce à la fois les mêmes problèmes? Quelqu'un peut-il m'aider à comprendre le problème?


0 commentaires

3 Réponses :


1
votes

Vous avez le Func Sélecteur Code> Paramètre. Cela signifie que vous avez la fonction reçoit le tsource code> objet et renvoie objet code>. Vous devez donc compiler votre boxingexpression et renvoyer le résultat:

     return Expression.Lambda<Func<T, object>>(boxingExpression, param).Compile();


1 commentaires

C'est exact. Mais lorsque je passe un objet directement à la méthode de tri, cela fonctionne. Je n'ai pas à faire une fonte explicite.



6
votes

Vous devez utiliser la version en boîte (vous Créer em> BoxingExpression code>, mais basez votre requête finale à la place sur ProcessionnaireXpression code>):

return Expression.Lambda<Func<T, object>>(boxingExpression, param).Compile();


2 commentaires

Ça a du sens. Si je ne me trompe pas, la conversion implicite est faite à l'heure de la compilation et l'exécution est totalement ignorée de cela. Comme les arbres d'expression sont exécutés au moment de l'exécution, doivent avoir un nœud de convertir pour la jeter. S'il vous plaît corrigez-moi si je n'ai pas compris correctement.


@Moorthy - Oui, la boxe est expliquée dans le compilateur (il y a un opcode pour cela). Un Conservation de référence-conservation Cast à un type de base est légal, cependant, et est un non-op (rien du tout n'est fait) - Vous pourriez trouver cela fonctionne correctement.



2
votes

Vous avez des prototypes getsortfunc comme renversant une instance Func <> qui renvoie un objet. À cause de cela, c'est votre travail de vous assurer que l'arborescence d'expression que vous générez donne un objet.

Bien que int en convertissez implicitement à un objet en C # sous la hotte, il est en train d'être en boîte. C'est pourquoi vous avez besoin de l'expression de boxe dans votre code et pourquoi vous devez générer la Lambda en utilisant l'expression que vous recevez de expression.convert . La meilleure façon d'y penser est que lorsque vous utilisez des arbres d'expression, vous devez expliquer toutes les conversions et ne pas y penser en termes de la manière dont vous écrivez le code C #.


0 commentaires