构建 LINQ 表达式树:如何获取范围内的变量

发布于 2024-09-12 07:09:45 字数 1485 浏览 2 评论 0原文

我正在构建一个 LINQ 表达式树,但它无法编译,因为据称局部变量 $var1 超出了范围:

从范围“”引用了“System.Object”类型的变量“”,但未定义

这是表达式树:

.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
}

以下代码负责构建树。它是更大的东西的一部分,因此我不希望从这个例子中完全清楚它的目的。

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()();

所以问题是:如何将局部变量纳入作用域以便表达式成功编译?

I'm building a LINQ expression tree but it won't compile because allegedly the local variable $var1 is out of scope:

variable '' of type 'System.Object' referenced from scope '', but it is not defined

This is the expression tree:

.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
}

The following code is responsible for building the tree. It is part of something larger, therefore I don't expect its purpose to be perfectly clear from this example.

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()();

So the question is: how do I get the local variable into scope so that the expression compiles succesfully?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泅人 2024-09-19 07:09:45

您将 Expression.Variable 添加到块中的“正常”表达式列表中 - 您应该 使用指定为块单独声明的变量的重载:(

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

并删除对 expressions.Add(resultVariable); 的调用)

Your'e adding the Expression.Variable to the list of "normal" expressions in the block - you should use the overload which specifies the variables do declare for the block separately:

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

(And remove the call to expressions.Add(resultVariable);)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文