Skip to main content

You are not logged in. Your edit will be placed in a queue until it is peer reviewed.

We welcome edits that make the post easier to understand and more valuable for readers. Because community members review edits, please try to make the post substantially better than how you found it, for example, by fixing grammar or adding additional resources and hyperlinks.

Required fields*

Compile deserialized Expression using Serialize.Linq

I'm not able to find the way how to compile the deserialized Expression using Serialize.Linq. The accepted answer in "Compile Expression at runtime Using Serialize.Linq" doesn't work (part 2 below):

using System.Linq.Expressions;
using Serialize.Linq.Extensions;
using Serialize.Linq.Serializers;

namespace ConsoleApp3;

internal class Program {

    static void Main() {
        Expression<Func<double, double, double>> distanceCalc =
            (x, y) => Math.Sqrt(x * x + y * y);
        var xParameter = Expression.Parameter(typeof(double), "x");
        var yParameter = Expression.Parameter(typeof(double), "y");
        var xSquared = Expression.Multiply(xParameter, xParameter);
        var ySquared = Expression.Multiply(yParameter, yParameter);
        var sum = Expression.Add(xSquared, ySquared);
        var sqrtMethod = typeof(Math).GetMethod("Sqrt", new[] { typeof(double) }) ?? throw new InvalidOperationException("Math.Sqrt not found!");
        var distance = Expression.Call(sqrtMethod, sum);
        var distanceLambda = Expression.Lambda<Func<double, double, double>>(
            distance,
            xParameter,
            yParameter);

        var serializer = new ExpressionSerializer(new Serialize.Linq.Serializers.JsonSerializer());
        string serializedExpression = serializer.SerializeText(distanceLambda);

        // part 1 works
        var de1 = serializer.DeserializeText(serializedExpression).ToExpressionNode().ToExpression<Func<double, double, double>>();
        var espre1 = de1.Compile();
        Console.WriteLine(espre1(3, 4));

        // part 2 as per "Compile Expression at runtime Using Serialize.Linq" doesn't work
        var de2 = serializer.DeserializeText(serializedExpression) as LambdaExpression;
        var espre2 = de2.Compile();
        // Console.WriteLine(espre2(3, 4)); compiler error on espre2 "Method name expected"

        // part 3 another problem
        var de3 = serializer.DeserializeText(serializedExpression).ToExpressionNode().ToExpression<Func<double, double, double>>();
        var t3 = de3.GetType();
        var tm3 = t3.GetMethod("Compile", []);
        var espre3 = tm3.Invoke(de3, []); // expre3 shows "Internal error evaluating expression" in debug
        // Console.WriteLine(espre3(3, 4)); compiler error on espre3 "Method name expected"
    }
}

Of cause, part 1 is not the way because "ToExpression<Func<double, double, double>>()" can't be applied (unknown).

Also, please explain the problem in the part 3

Answer*

Cancel
2
  • ".ToExpressionNode()" is extra and causes an error. Also ".Method.Invoke(null, [null, 3, 4 ])" looks more complex than ".DynamicInvoke(3, 4)"
    – rotabor
    Commented Apr 8, 2024 at 6:46
  • @rotabor DynamicInvoke may work for you, it may not. Try it and see. The parameters get boxed to object?[]? either way. And I copied part of your deserialize code because I don't use the library.
    – Corey
    Commented Apr 8, 2024 at 8:31