【问题标题】:"variable '' of type '' referenced from scope '', but it is not defined"“从范围''引用''类型的变量'',但未定义”
【发布时间】:2018-08-09 23:20:09
【问题描述】:

我的代码收到此错误消息:“从范围 '' 引用的类型为 'System.Int32' 的变量 'assignVal',但未定义”

我签了

但不幸的是,我的示例似乎更简单,但由于某种原因仍然无法正常工作。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection.Emit;
using System.Threading.Tasks;
using static System.Linq.Expressions.Expression;

namespace ExpressionTests
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine(GetSyncAddExpression()(5) == 6);
            Console.ReadKey();

            Console.WriteLine(await GetTaskAddExpression()(5) == 6);
            Console.ReadKey();
        }

        private static Func<int, Task<int>> GetTaskAddExpression()
        {
            var fromResultMethod = typeof(Task).GetMethod(nameof(Task.FromResult)).MakeGenericMethod(typeof(int));

            var inParam = Parameter(typeof(int), "p1");
            var assignmentValue = Variable(typeof(int), "assignVal");
            var retVal = Variable(typeof(Task<int>));

            var lambda = Lambda<Func<int, Task<int>>>(Block(
                Assign(assignmentValue, Add(inParam, Constant(1))),
                Assign(retVal, Call(null, fromResultMethod, assignmentValue)),
                retVal
            ), inParam);

            if (Debugger.IsAttached)
                Debugger.Break();

            return lambda.Compile();
        }

        private static Func<int, int> GetSyncAddExpression()
        {
            var inParam = Parameter(typeof(int), "p1");
            var assignmentValue = Variable(typeof(int), "assignVal");
            var retVal = Variable(typeof(int));

            var lambda = Lambda<Func<int, int>>(Block(
                Assign(assignmentValue, Add(inParam, Constant(1))),
                Assign(retVal, assignmentValue),
                retVal
            ), inParam);

            if (Debugger.IsAttached)
                Debugger.Break();

            return lambda.Compile();
        }
    }
}

这个代码示例看起来很简单,应该可以按原样工作,而且我正在重用表达式,所以我不太明白为什么会出现这个错误。

【问题讨论】:

  • 错误发生在哪一行?
  • @Claies .Compile 调用导致错误发生。
  • 是的,但是代码中的哪一行导致错误发生?您的问题正文说错误与 variable 'assignVal' 有关,但您发布的代码中没有该名称的变量。
  • @Claies 我的错。当我添加更多样本时重命名变量 - 它是“assignmentValue”
  • 除非其中的异步部分实际上是相关的,否则如果您删除它会简化事情。我会先让同步器工作。

标签: c# expression


【解决方案1】:

您没有在Block 调用中包含要使用的变量。

如果你改变这个:

var lambda = Lambda<Func<int, int>>(Block(
    Assign(assignmentValue, Add(inParam, Constant(1))),
    Assign(retVal, assignmentValue),
    retVal
), inParam);

到这里:

var lambda = Lambda<Func<int, int>>(Block(
    // This is the line I've added
    new[] { assignmentValue, retVal },
    Assign(assignmentValue, Add(inParam, Constant(1))),
    Assign(retVal, assignmentValue),
    retVal
), inParam);

效果很好。

基本上你使用的是Block(params Expression[]) 重载,它只适用于没有变量的块。

【讨论】:

  • 哈!只是自己想出了一个。不会忘记那个,看看它有多明显。这些方法的智能感知被过滤掉了。非常感谢!
【解决方案2】:

对于从谷歌点击这个的人 ->

此代码适用于两者 - 也适用于任务。黛西是第一个回答的。所以给他/她点赞

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq.Expressions;
using System.Reflection.Emit;
using System.Threading.Tasks;
using static System.Linq.Expressions.Expression;

namespace ExpressionTests
{
    class Program
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine(GetSyncAddExpression()(5) == 6);
            Console.ReadKey();

            Console.WriteLine(await GetTaskAddExpression()(5) == 6);
            Console.ReadKey();
        }

        private static Func<int, Task<int>> GetTaskAddExpression()
        {
            var fromResultMethod = typeof(Task).GetMethod(nameof(Task.FromResult)).MakeGenericMethod(typeof(int));

            var inParam = Parameter(typeof(int), "p1");
            var assignmentValue = Variable(typeof(int), "assignVal");
            var retVal = Variable(typeof(Task<int>));

            var lambda = Lambda<Func<int, Task<int>>>(Block(
                new[] { assignmentValue, retVal },
                Assign(assignmentValue, Add(inParam, Constant(1))),
                Assign(retVal, Call(null, fromResultMethod, assignmentValue)),
                retVal
            ), inParam);

            if (Debugger.IsAttached)
                Debugger.Break();

            return lambda.Compile();
        }

        private static Func<int, int> GetSyncAddExpression()
        {
            var inParam = Parameter(typeof(int), "p1");
            var assignmentValue = Variable(typeof(int), "assignVal");
            var retVal = Variable(typeof(int));

            var lambda = Lambda<Func<int, int>>(Block(
                new[] {assignmentValue, retVal},
                Assign(assignmentValue, Add(inParam, Constant(1))),
                Assign(retVal, assignmentValue),
                retVal
            ), inParam);

            if (Debugger.IsAttached)
                Debugger.Break();

            return lambda.Compile();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2015-10-08
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多