表达式树产生参数异常

Expression tree yields Argument exception

我有以下代码,一切正常,直到我到达最后一行失败并出现以下异常:

Method 'Boolean Contains(System.Linq.Expressions.ConstantExpression)' declared on type 'System.Collections.Generic.List`1[System.Linq.Expressions.ConstantExpression]' cannot be called with instance of type 'System.Guid'

var filter = new List<SomeObj> { new SomeObj { Id = "<guid-string>" }};

var lookupExpression = filter.SetOperand.Select(x => Expression.Constant(Guid.Parse(x.Id))).ToList();
var arrayOfValues = Expression.NewArrayInit(typeof(Guid), lookupExpression);
var arrayType = lookupExpression.GetType();
var containsMethod = arrayType.GetMethod("Contains");

var right = Expression.Call(dataProperty, containsMethod, arrayOfValues);

我认为问题在于 dataProperty 是从动态构造的表达式中读取的,该表达式始终是 Guid,因此当方法执行时,它将此对象视为 Guid,而方法和列表都是 List。还有其他解决方法吗?

我不太明白你想做什么或为什么,但这是我猜测如何修复你的代码:

  1. 您不想检查您的 GUID 表达式集合 (lookupExpression) 是否包含给定的 GUID,您想要检查您的 GUID 集合 (arrayOfValues) 可以。也就是说arrayType是错误的,应该是:var arrayType = arrayOfValues.Type;.
  2. 如果arrayOfValues实际上是数组,你不能使用Contains实例方法,因为数组没有。

    您可以使用 LINQ Contains,或将 arrayOfValues 更改为表示 List<Guid> 而不是 Guid[] 的表达式。我选择了 LINQ。

    获取LINQ Contains方法,可以使用LINQ:

    var containsMethod = typeof(Enumerable).GetMethods()
        .Single(m => m.Name == "Contains" && m.GetParameters().Length == 2)
        .MakeGenericMethod(typeof(Guid));
    
  3. 您的 Call() 顺序错误,即使 List.Contains() 也是如此。对于 LINQ Contains,正确的顺序是:

    Expression.Call(containsMethod, arrayOfValues, dataProperty)