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);
}