dynamicexpresso / DynamicExpresso

C# expressions interpreter
http://dynamic-expresso.azurewebsites.net/
MIT License
1.99k stars 374 forks source link

Using Lambda expression inside a Lambda expression #256

Closed mohamedabdelmonem-E closed 2 years ago

mohamedabdelmonem-E commented 2 years ago

When trying to call lambda expression form another lambda expression an exception is thrown (different exceptions when tweaking the code differently) below is an example of the code required to get evaluated:

using DynamicExpresso;
using System.Collections.Generic;
using System.Linq;

namespace TEST
{
    class Program
    {
        static void Main(string[] args)
        {
            ICollection<BounsMatrix> annualBouns = new List<BounsMatrix> {
                new() { Grade = 1, BounsFactor = 7 }, 
                new() { Grade = 2, BounsFactor = 5.5 }, 
                new() { Grade = 3, BounsFactor = 4 }, 
                new() { Grade = 4, BounsFactor = 3.5 }, 
                new() { Grade = 5, BounsFactor = 3 } 
            };

            ICollection<Employee> employees = new List<Employee> {
                new() { Id = "01", Name = "A", Grade = 5, Salary = 20000}, //bouns = 20000 * 7   = 60000
                new() { Id = "02", Name = "B", Grade = 5, Salary = 18000}, //bouns = 18000 * 7   = 54000
                new() { Id = "03", Name = "C", Grade = 4, Salary = 12000}, //bouns = 12000 * 5.5 = 42000
                new() { Id = "04", Name = "D", Grade = 4, Salary = 10000}, //bouns = 10000 * 5.5 = 35000
                new() { Id = "05", Name = "E", Grade = 3, Salary = 8500},  //bouns = 8500  * 4   = 34000
                new() { Id = "06", Name = "F", Grade = 3, Salary = 8000},  //bouns = 8000  * 4   = 32000
                new() { Id = "07", Name = "G", Grade = 2, Salary = 5000},  //bouns = 5000  * 3.5 = 27500
                new() { Id = "08", Name = "H", Grade = 2, Salary = 4750},  //bouns = 4750  * 3.5 = 26125
                new() { Id = "09", Name = "I", Grade = 1, Salary = 3500},  //bouns = 3500  * 3   = 24500
                new() { Id = "10", Name = "J", Grade = 1, Salary = 3250}   //bouns = 3250  * 3   = 22750
            };

            var interpreter = new Interpreter(InterpreterOptions.LambdaExpressions | InterpreterOptions.Default);
            interpreter.SetVariable(nameof(annualBouns), annualBouns);
            interpreter.SetVariable(nameof(employees), employees);

            var totalBouns = employees.Sum(x => x.Salary * (annualBouns.SingleOrDefault(y => y.Grade == x.Grade).BounsFactor)); //total = 357875

            var x = interpreter.Eval("employees.Sum(x => x.Salary * (annualBouns.SingleOrDefault(y => y.Grade == x.Grade).BounsFactor))");
        }

        public class Employee
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public int Grade { get; set; }
            public double Salary { get; set; }
        }

        public class BounsMatrix
        {
            public int Grade { get; set; }
            public double BounsFactor { get; set; }
        }
    }
}
metoule commented 2 years ago

Fixed in #257 (thanks to @holdenmai!)