Construire un arbre d’expression LINQ: comment obtenir une variable dans la portée

.net c# expression-trees lambda linq

Question

Je suis en train de construire un arbre d’expression LINQ mais il ne sera pas compilé, car la variable locale $var1 n’est pas à sa portée:

la variable '' de type 'System.Object' référencée depuis scope '', mais elle n'est pas définie

C'est l'arbre d'expression:

.Block() {
    $var1;
    .If ($n.Property1 == null) {
        .Block() {
            $var1 = null;
            .Return #Label1 { }
        }
    } .Else {
        .Default(System.Void)
    };
    $var1 = (System.Object)($n.Property1).Length;
    .Label
    .LabelTarget #Label1:;
    $var1
}

Le code suivant est responsable de la construction de l'arborescence. Cela fait partie de quelque chose de plus grand, donc je ne m'attends pas à ce que son objectif soit parfaitement clair à partir de cet exemple.

MemberExpression sourceExpression = ...;

List<Expression> expressions = new List<Expression>();
LabelTarget returnTarget = Expression.Label();
ParameterExpression resultVariable = Expression.Variable(typeof(object));

expressions.Add(resultVariable);

expressions.Add(
    Expression.IfThen(
        Expression.Equal(sourceExpression, Expression.Constant(null)),
        Expression.Block(
            Expression.Assign(resultVariable, Expression.Constant(null)),
            Expression.Return(returnTarget))));

expressions.Add(
    Expression.Assign(
        resultVariable,
        Expression.Convert(sourceExpression, typeof(object))));

expressions.Add(Expression.Label(returnTarget));
expressions.Add(resultVariable);

Expression finalExpression = Expression.Block(expressions);
object result = Expression.Lambda<Func<object>>(finalExpression).Compile()();

La question est donc: comment puis-je obtenir la variable locale dans la portée afin que l'expression soit compilée avec succès?

Réponse acceptée

Vous ajoutez la variable Expression.Variable à la liste des expressions "normales" du bloc; vous devez utiliser la surcharge qui spécifie les variables déclarées séparément pour le bloc :

Expression finalExpression = Expression.Block(new[] { resultVariable },
                                              expressions);

(Et supprimez l'appel à expressions.Add(resultVariable); )




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi