0

I'm using codingseb / ExpressionEvaluator and I'm trying to create a new operator "in" that returns a boolean value of true if the searched item is in the specified field. It should work like this:

ara = Array(1, 8, 15, true, "string", 18, 25, 30)
sea = 18
tr = sea in ara
fa = false in ara

Expected results: tr should contain true, fa false.

Complete editable live example, but not working.

My actual code is based on wiki Add your own simple operator, but I can't create Predicate part (lambda expression) in Array.Exists<T>(T[], Predicate<T>). I am getting an error: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.

Can you help me how to modify the code to use this Array.Exists method?

public class XExpressionOperator : ExpressionOperator
{
    public static readonly ExpressionOperator InArray = new XExpressionOperator();
}

public class EE : ExpressionEvaluator
{
    protected new static readonly IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> operatorsEvaluations =
        ExpressionEvaluator.operatorsEvaluations
            .Copy()
            .AddOperatorEvaluationAtNewLevelAfter(XExpressionOperator.InArray, (dynamic left, dynamic right) => {
            if (right is Array) {
              // error in next line at (object item)
              return Array.Exists<object>(right, (object item) => {
                  return left == item;
              });
            }
            return false;
            }, XExpressionOperator.UnaryPlus);

    protected override IList<IDictionary<ExpressionOperator, Func<dynamic, dynamic, object>>> OperatorsEvaluations => operatorsEvaluations;

    protected override void Init()
    {
        operatorsDictionary.Add("in", XExpressionOperator.InArray);
    }
}

Edit

I managed to bypass the problem with this solution (live demo). However, I still don't know how to exactly create an expression of type Expression<Func<...>>. That would probably be the correct solution to this problem.

My partial solution is to retype right to object[]:

(dynamic left, dynamic right) => {
  if (right is IEnumerable<dynamic>) {
    object[] objectArray = right;
    return Array.Exists(objectArray, (item) => {
      return item.Equals(left);
    });
  }
  return ((object)left).Equals(right);
}
Atiris
  • 2,613
  • 2
  • 28
  • 42

0 Answers0