Skip to content

An expression with a single parameter concatenated to a string causes 'Exception has been thrown by the target of an invocation' during delegate invocation. #404

@Rotabor

Description

@Rotabor

An expression with a single parameter concatenated to a string causes 'Exception has been thrown by the target of an invocation' during delegate invocation while the same expression compiled by 'System.Linq.Expressions.LambdaExpression.Compile' is invoked successfully.
An expression with two parameters, where the result of an operation with them is concatenated to a string, doesn't cause such error.
The sample code below uses DynamicExpresso (NuGet 'DynamicExpresso.Core') library. It's used to produce the required expression. At the same time, it seems to be not related to the issue.

// .Net 8.0
using System.Linq.Expressions;
using FastExpressionCompiler;
using DynamicExpresso;

namespace ConsoleApp3;

internal class Program {

    internal static LambdaExpression GetLambdaExpression(Expression expression, Type delegateType, Parameter[] parameters) {
        Type[] genericArguments = delegateType.GetGenericArguments();
        genericArguments[^1] = expression.Type;
        return Expression.Lambda(delegateType.GetGenericTypeDefinition().MakeGenericType(genericArguments), expression, parameters.Select((Parameter p) => p.Expression).ToArray());
    }

    static void Main() {
        Interpreter interpreter = new();

        Console.WriteLine("Expression with a single parameter");
        Console.WriteLine(new String('-', 80));
        var exprns1 = "\"The value is \" + erty";
        Parameter[] parameters1 = [new Parameter("erty", Activator.CreateInstance(Type.GetType("System.Double")))];
        var expression1 = interpreter.Parse(exprns1, parameters1).Expression;
        Console.WriteLine("Expression --> " + expression1);
        var delegateType1 = Expression.GetFuncType(typeof(double), typeof(string));
        var le1 = GetLambdaExpression(expression1, delegateType1, parameters1);
        Console.WriteLine("Lambda xpression --> " + le1);
        Console.WriteLine(new String('-', 80));
        Delegate dlg1 = le1.CompileFast();
        string? res1 ="";
        Console.WriteLine("CompileFast");
        try { res1 = (string)dlg1.DynamicInvoke(3.14); } catch (Exception ex) { Console.WriteLine(ex.Message); }
        Console.WriteLine(res1);
        Console.WriteLine(new String('-', 80));

        Console.WriteLine("Compile");
        dlg1 = le1.Compile();
        res1 = "";
        try { res1 = (string)dlg1.DynamicInvoke(3.14); } catch (Exception ex) { Console.WriteLine(ex.Message); }
        Console.WriteLine(res1);
        Console.WriteLine(new String('-', 80));
        Console.WriteLine("\r\n");


        Console.WriteLine("Expression with two parameters");
        Console.WriteLine(new String('-', 80));
        var exprns2 = "\"The value is \" + (erty + dfgh)";
        Parameter[] parameters2 = [
            new Parameter("erty", Activator.CreateInstance(Type.GetType("System.Double"))),
            new Parameter("dfgh", Activator.CreateInstance(Type.GetType("System.Double"))),
        ];
        var expression2 = interpreter.Parse(exprns2, parameters2).Expression;
        Console.WriteLine("Expression --> " + expression2);
        var delegateType2 = Expression.GetFuncType(typeof(double), typeof(double), typeof(string));
        var le2 = GetLambdaExpression(expression2, delegateType2, parameters2);
        Console.WriteLine("Lambda xpression --> " + le2);
        Console.WriteLine(new String('-', 80));
        Delegate dlg2 = le2.CompileFast();
        string? res2 = "";
        Console.WriteLine("CompileFast");
        try { res2 = (string)dlg2.DynamicInvoke(3.1415, 2.7183); } catch (Exception ex) { Console.WriteLine(ex.Message); }
        Console.WriteLine(res2);
        Console.WriteLine(new String('-', 80));
    }
}

Result:

Expression with a single parameter
--------------------------------------------------------------------------------
Expression --> Concat("The value is ", IIF((ConvertChecked(erty, Nullable`1) == null), null, erty.ToString()))
Lambda xpression --> erty => Concat("The value is ", IIF((ConvertChecked(erty, Nullable`1) == null), null, erty.ToString()))
--------------------------------------------------------------------------------
CompileFast
Exception has been thrown by the target of an invocation.

--------------------------------------------------------------------------------
Compile
The value is 3,14
--------------------------------------------------------------------------------


Expression with two parameters
--------------------------------------------------------------------------------
Expression --> Concat("The value is ", IIF((ConvertChecked((erty + dfgh), Nullable`1) == null), null, (erty + dfgh).ToString()))
Lambda xpression --> (erty, dfgh) => Concat("The value is ", IIF((ConvertChecked((erty + dfgh), Nullable`1) == null), null, (erty + dfgh).ToString()))
--------------------------------------------------------------------------------
CompileFast
The value is 5,8598
--------------------------------------------------------------------------------

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions