12
votes

Expression dynamique LINQ avec valeur de retour

J'ai besoin de créer une expression dynamique Linq et j'ai commencé à travailler avec de nombreux exemples. J'ai testé certains et certains travaillent et certains pas. Dans ce cas, je veux créer une méthode qui ressemble à: xxx

maintenant j'ai écrit ce qui suit: xxx

maintenant il jette < Code> InvalidOperationException :

ne peut pas sauter à l'étiquette "Label" `

Qu'est-ce qui ne va pas? J'ai seulement besoin d'un retour vrai ou de faux.


1 commentaires

Pouvez-vous nous en dire un peu plus sur ce que vous essayez d'atteindre? Par exemple, pourquoi avez-vous besoin de créer de manière dynamique cette expression ... et pourquoi devez-vous utiliser des étiquettes et si else quand vous pourriez écrire: chèque Bool public (int totvar) {retour I> 2; }


3 Réponses :


1
votes

returnTarget code> n'est actuellement référencé par votre if / then / else instruction. L'étiquette est pas placé dans la déclaration nulle part. Donc, il ne sait pas où sauter. L'étiquette est uniquement défini et référencé, mais pas placé.

Essayez d'utiliser Expression.Block code> pour combiner votre lambda et l'étiquette. P>

Expression.Lambda<Action<int>>(
    Expression.Block(
        this.TheExpression,
        Expression.Label(returnTarget)
    ),
    new ParameterExpression[] { para }
    ).Compile()(5);


0 commentaires

20
votes

Vous devez changer quelques points:

  • Placez l'étiquette de retour au bas de votre fonction dans une expression de bloc, comme suggéré René. C'est ici que votre relève de votre retour sautera.

  • Déclarez la Lambda en tant que type Func . Puisque vous voulez une valeur de retour, cela doit être une fonction, pas une action.

  • déclarer le returntarget étiquette comme type bool . Étant donné que la valeur de retour d'une expression de bloc est la valeur de sa dernière instruction, l'étiquette doit être du type correct.

  • Fournissez une valeur par défaut pour l'étiquette finale (= la valeur de retour de votre fonction si l'étiquette est atteinte par le flux de contrôle normal au lieu d'une instruction de retour ). XXX


1 commentaires

Si vous regardez un code IL compilé, vous pouvez voir qu'il n'a jamais vraiment quitté ...;)



2
votes

Si vous avez une déclaration de condition simple comme celle-ci:

Expression condition;
Expression expression1;
Expression expression2;
/* ... */
Expression body = Expression.Condition(
    test:    condition,
    ifTrue:  expression1,
    ifFalse: expression2);


0 commentaires