将In和NotIn添加到System.Linq.Expressions.Expression中,是否可能?

问题描述 投票:3回答:1

我正在尝试创建一个InNotIn表达式操作或基本上扩展System.Linq.Expressions.Expression,以便能够检查属性值是否在属性值列表的数组中,但我不知道它是否可能。

我正在阅读this article,它说“没有办法执行一系列任意操作”。我不知道是否可以创建这些新操作或从哪里开始。任何帮助或提示将不胜感激。

public static BinaryExpression MakeBinary(
  ExpressionType binaryType, 
  Expression left, 
  Expression right)
c# linq expression
1个回答
1
投票

你可以调用Enumerable.Contains方法。

static Expression<Func<IEnumerable<string>, bool>> containsExpr = en => en.Contains(null);
static MethodInfo containsMethodInfo = ((MethodCallExpression)containsExpr.Body).Method.GetGenericMethodDefinition();

public static Expression In(this Expression value, Expression arrayOfValues)
{
    return Expression.Call(containsMethodInfo.MakeGenericMethod(arrayOfValues.Type.GetElementType()),
            arrayOfValues, value);
}

public static Expression NotIn(this Expression value, Expression arrayOfValues)
{
    return Expression.Not(In(value, arrayOfValues));
}

然后你可以像这样调用它:

public class Foo { public int FooValue { get; set; } }

public void ExpressionInArray()
{
    var propertyReference = MemberExpression.Property(Expression.Constant(new Foo() { FooValue = 3 }), "FooValue");
    var validValues = Expression.Constant(new[] { 3, 4, 5 });
    var invalidValues = Expression.Constant(new[] { 6, 7, 8 });

    var expressionEvaluatingToTrue = propertyReference.In(validValues);
    var expressionEvaluatingToFalse = propertyReference.In(invalidValues);

    var expressionEvaluatingToTrue2 = propertyReference.NotIn(invalidValues);
    var expressionEvaluatingToFalse2 = propertyReference.NotIn(validValues);
}

假设该类型是一个数组,而不仅仅是任何旧的IEnumerable<T>。如果你必须采取任何旧的IEnumerable<T>,你必须将arrayOfValues.Type.GetElementType()更改为需要arrayOfValues.Type并在其上找到适当的IEnumerable<T>实现并从该接口返回泛型参数。

© www.soinside.com 2019 - 2024. All rights reserved.