The expression calls the constructor with the parameter and sets its value

I am trying to call a parameterized constructor from an expression instead of using the default ctor. this is the code that gets the constructor parameter:

ConstructorInfo ci = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, new[] { typeof(bool) }, new ParameterModifier[] { }); ParameterInfo[] paramsInfo = ci.GetParameters(); //create a single param of type object[] ParameterExpression param = Expression.Parameter(typeof(bool), "il"); Expression[] argsExp = new Expression[paramsInfo.Length]; //pick each arg from the params array //and create a typed expression of them for (int i = 0; i < paramsInfo.Length; i++) { Expression index = Expression.Constant(i); Type paramType = paramsInfo[i].ParameterType; Expression paramAccessorExp = param; //Expression.ArrayIndex(param, index); Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType); argsExp[i] = param; } NewExpression ci2 = Expression.New(ci, argsExp); 

But if I try to compile a lambda expression, I get the following error:

variable 'il' of type 'System.Boolean' referring to scope '' but not defined

What am I missing? Any help and / or hint appreciated.

+4
source share
2 answers

You define a parameter named li in the 4th line of your code. To use this in a lambda expression, you need to have a scope in which this parameter is defined. You have two options:

  • Create a BlockExpression that contains param as a local variable. Then use this expression as the body of your lambda expression.
  • Use param as a parameter in LambdaExpression .

If you use option 1, you will also have to initialize the variable. Otherwise, you will receive a different type of error message.

EDIT

There are two problems with the additional code you added:

  • You need to use the same parameter object in the entire expression tree. Having the same name and type does not make two Parameter objects equal. I would just move everything up and include the lambda in the ConvertThis method ConvertThis that you can reuse the param variable. Then you can simply compile the return value of ConvertThis to get your delegate.

  • When creating BlockExpression you need to pass param as a local variable. You do this by adding the argument new ParameterExpression[] { param } to the method.

+3
source

Try

 ParameterExpression param = Expression.Parameter(typeof(bool); 
+1
source

Source: https://habr.com/ru/post/1381729/


All Articles