Search code examples
c#dynamic-expresso

Dynamic expresso foreach with lambda?


I am using Dynamic-Expresso library. I would like to evaluate expression containing foreach statement. Is that possible? The only way I can see is to write parametrized method and send the whole class as a parameter to the Interpreter

var target = new Interpreter();
target.SetVariable("a", a, typeof(Tools));
target.SetVariable("b", b, typeof(List<param>));
if (target.Eval("a.MethodWithForeach(b)").Equals(true))
{
 ...
}

Solution

  • You are right, for now there isn't an easy way to work with collections. I already have a plan to work on this feature but I don't known an exact release date.

    For now, as a workaround, you can write some helpers like the one below:

    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Collections.Generic;
    
    namespace DynamicExpresso.UnitTest
    {
        [TestClass]
        public class CollectionHelperTests
        {
            [TestMethod]
            public void Where()
            {
                var target = new Interpreter();
    
                target.SetVariable("IntCollectionHelper", new CollectionHelper<int>());
    
                var list = new List<int> { 1, 10, 19, 21 };
    
                var results = target.Eval("IntCollectionHelper.Where(list, \"x > 19\")", new Parameter("list", list))
                                        as IEnumerable<int>;
    
                Assert.AreEqual(1, results.Count());
                Assert.AreEqual(21, results.First());
            }
        }
    
        public class CollectionHelper<T>
        {
            readonly Interpreter _interpreter;
    
            public CollectionHelper()
            {
                _interpreter = new Interpreter();
            }
    
            public IEnumerable<T> Where(IEnumerable<T> values, string expression)
            {
                var predicate = _interpreter.Parse<Func<T, bool>>(expression, "x");
    
                return values.Where(predicate);
            }
        }
    }
    

    Basically I have created a little helper to simulate some LINQ functions (Where in the above example). You can then call this helper from your expressions.