我正在尝试构建一个谓词构建器,该构建器返回一个谓词,该谓词检查一个int列表是否包含另一个int列表。到目前为止我有这个
public static Expression<Func<T, bool>> DynamicIntContains<T, TProperty>(string property, IEnumerable<TProperty> items)
{
var pe = Expression.Parameter(typeof(T));
var me = Expression.Property(pe, property);
var ce = Expression.Constant(items);
var call = Expression.Call(typeof(List<int>), typeof(List<int>).GetMethod("Contains").Name, new[] { typeof(int) }, ce, me);
return Expression.Lambda<Func<T, bool>>(call, pe);
}
T是搜索对象,其中包含作为其属性之一的ID列表。 TProperty是一个int列表,属性是属性列表的名称。我得到的错误是
Additional information: No method 'Contains' exists on type 'System.Collections.Generic.List`1[System.Int32]'.
这是因为我是从静态方法调用它吗?或者我是否尝试错误地访问typeof(List)上的方法?谢谢。
答案 0 :(得分:1)
这是解决方案;
public static Expression<Func<T, bool>> DynamicIntContains<T, TProperty>(string property, IEnumerable<TProperty> items, object source, PropertyInfo propertyInfo)
{
var pe = Expression.Parameter(typeof(T));
var me = Expression.Property(pe, property.Singularise());
var ce = Expression.Constant(propertyInfo.GetValue(source, null), typeof(List<int>));
var convertExpression = Expression.Convert(me, typeof(int));
var call = Expression.Call(ce, "Contains", new Type[] { }, convertExpression);
return Expression.Lambda<Func<T, bool>>(call, pe);
}
这是假设列表名称是其成员的复数。在Expression.Call中我传递了一个typeof(List),正确的方法是传入Type []。似乎还需要将MemberExpression转换为特定类型的常量。感谢。
答案 1 :(得分:-2)
你走了:
class Program
{
static void Main(string[] args)
{
var t1 = new List<int> {1, 3, 5};
var t2 = new List<int> {1, 51};
var s = new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9};
Console.WriteLine(s.Contains(t1));
Console.WriteLine(s.Contains(t2));
}
}
public static class Extensions
{
public static bool Contains(this List<int> source, List<int> target)
{
return !target.Except(source).Any();
}
}
和通用表格:
public static bool Contains<T>(this List<T> source, List<T> target)
{
return !target.Except(source).Any();
}
更通用:
public static bool Contains<T>(this IEnumerable<T> source, IEnumerable<T> target)
{
return !target.Except(source).Any();
}