您可以为此使用反射和动态表达式的组合。我整理了一个样本,乍一看可能看起来有点长。但是,它符合您的要求并通过
解决这些问题
- 使用反射查找字符串类型的属性并匹配属性名称 - 如果提供的话。
- 创建一个调用字符串的表达式。包含已识别的所有属性。如果已识别多个属性,则对 string.Contains 的调用由 Or 表达式组合。这个过滤器表达式被编译并作为参数传递给 Where 扩展方法。使用表达式过滤提供的列表。
按照此link 运行示例。
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
public class Test
{
public static IEnumerable<T> SelectItems<T>(IEnumerable<T> items, string propName, string value)
{
IEnumerable<PropertyInfo> props;
if (!string.IsNullOrEmpty(propName))
props = new PropertyInfo[] { typeof(T).GetProperty(propName) };
else
props = typeof(T).GetProperties();
props = props.Where(x => x != null && x.PropertyType == typeof(string));
Expression lastExpr = null;
ParameterExpression paramExpr = Expression.Parameter(typeof(T), "x");
ConstantExpression valueExpr = Expression.Constant(value);
foreach(var prop in props)
{
var propExpr = GetPropertyExpression(prop, paramExpr, valueExpr);
if (lastExpr == null)
lastExpr = propExpr;
else
lastExpr = Expression.MakeBinary(ExpressionType.Or, lastExpr, propExpr);
}
if (lastExpr == null)
return new T[] {};
var filterExpr = Expression.Lambda(lastExpr, paramExpr);
return items.Where<T>((Func<T, bool>) filterExpr.Compile());
}
private static Expression GetPropertyExpression(PropertyInfo prop, ParameterExpression paramExpr, ConstantExpression valueExpr)
{
var memberAcc = Expression.MakeMemberAccess(paramExpr, prop);
var containsMember = typeof(string).GetMethod("Contains");
return Expression.Call(memberAcc, containsMember, valueExpr);
}
class TestClass
{
public string SomeProp { get; set; }
public string SomeOtherProp { get; set; }
}
public static void Main()
{
var data = new TestClass[] {
new TestClass() { SomeProp = "AAA", SomeOtherProp = "BBB" },
new TestClass() { SomeProp = "BBB", SomeOtherProp = "CCC" },
new TestClass() { SomeProp = "CCC", SomeOtherProp = "AAA" },
};
var result = SelectItems(data, "", "A");
foreach(var item in result)
Console.WriteLine(item.SomeProp);
}
}
与完全基于反射的方法相比,这种方法只组装一次过滤器表达式并对其进行编译,因此我期望性能有(小的)改进。