Dbl
Dbl

Reputation: 5893

"variable '' of type '' referenced from scope '', but it is not defined"

I am getting this error message for my code: "variable 'assignVal' of type 'System.Int32' referenced from scope '', but it is not defined"

I checked out

but unfortunately my sample seems way more simple and still doesn't work for some reason.

This is my code:

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

This code sample seems simple enough that it should be working as is and i'm reusing the expressions, so i don't quite understand why i'm getting this error.

Upvotes: 4

Views: 3303

Answers (2)

Dbl
Dbl

Reputation: 5893

For people hitting this from google ->

This code works for both - Tasks too. Daisy was first to answer though. so give him/her the upvotes

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

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499770

You aren't including the variables you want to use in your Block call.

If you change this:

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

To this:

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

it works fine.

Basically you're using the Block(params Expression[]) overload, which is only suitable for blocks that have no variables.

Upvotes: 6

Related Questions