您好我必须在泛型类应用滤镜。 示例类是如下
public class Sample<T>
{
List<T> sourceList = new List<T>();
public void applyFilter(string propertyName , EnumOperator operator , object value)
{
}
}
在这里,我想使用LINQ或动态LINQ来实现过滤器,但我没有得到任何积极的方向来实现这一功能。
请给我一些积极的方向,这样我可以实现这个功能。
谢谢。
我会建议返回一个过滤列表,而不是修改源,也是字符串“经营者”是一个C#的关键字,因此该方法的签名可能是:
public List<T> ApplyFilter(string propertyName, EnumOperator operatorType, object value)
{
....
}
在这里我假设EnumOperator
是一个enum
有这样的价值观:
public enum EnumOperator
{
Equal,
NotEqual,
Bigger,
Smaller
}
并且您有一些方法来检查,如果操作员的值是通过还是未通过测试,沿着线的东西:
public static class OperatorEvaluator
{
public static bool Evaluate(EnumOperator operatorType, object first, object second)
{
...
}
}
鉴于这种情况,你可以这样做:
public List<T> ApplyFilter(string propertyName , EnumOperator operatorType, object value)
{
PropertyInfo pi = typeof(T).GetProperty(propertyName);
List<T> result = sourceList.Where(item => {
var propValue = pi.GetValue(item, null);
return OperatorEvaluator.Evaluate(operatorType, propValue, value);
}).ToList();
return result;
}
这就是说,你可以随时使用LINQ的方法,而不是诉诸反射来过滤几乎所有的东西。
要使用动态表情(如字符串)查询,您可以使用动态LINQ由斯科特谷微软的。
样品
它支持以下操作
1.选择
2.凡
3.排序依据
4.跳过
5.取
6.的GroupBy
上述所有操作都字符串作为参数。
它也有小的表达式语言(建选择/谓词/等),这是非常容易使用。
例:
var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");
在这里,我给你一个样品例如如何使用LINQ来实现过滤List<T>
的项目..
public class clsCountry
{
public string _CountryCode;
public string _CountryName;
//
public clsCountry(string strCode, string strName)
{
this._CountryCode = strCode;
this._CountryName = strName;
}
//
public string CountryCode
{
get {return _CountryCode;}
set {_CountryCode = value;}
}
//
public string CountryName
{
get { return _CountryName; }
set { _CountryName = value; }
}
}
现在,让我们创建一个基于类对象的列表clsCountry
并将其存储在一个List<T>
对象。
List<clsCountry> lstCountry = new List<clsCountry>();
lstCountry.Add(new clsCountry("USA", "United States"));
lstCountry.Add(new clsCountry("UK", "United Kingdom"));
lstCountry.Add(new clsCountry("IND", "India"));
接下来,我们将结合List<T>
对象lstCountry到DropDownList
命名drpCountry作为等作为控制:
drpCountry.DataSource = lstCountry;
drpCountry.DataValueField = "CountryCode";
drpCountry.DataTextField = "CountryName";
drpCountry.DataBind();
现在,使用LINQ从lstCountry对象过滤数据并结合过滤列表的下拉控制drpCountry。
var filteredCountries = from c in lstCountry
where c.CountryName.StartsWith("U")
select c;
drpCountry.DataSource = filteredCountries;
drpCountry.DataValueField = "CountryCode";
drpCountry.DataTextField = "CountryName";
drpCountry.DataBind();
现在,下拉控制将只有2项
美国
英国
现在适用于你的情况下,这些技术..
您可以使用反射检索属性值,你可以使用一个简单的switch
的操作者的语句进行过滤:
public IEnumerable<T> ApplyFilter(string propertyName, EnumOperator op, object value)
{
foreach (T item in sourceList)
{
object propertyValue = GetPropertyValue(item, propertyName);
if (ApplyOperator(item, propertyValue, op, value)
{
yield return item;
}
}
}
private object GetPropertyValue(object item, string propertyName)
{
PropertyInfo property = item.GetType().GetProperty(propertyName);
//TODO handle null
return property.GetValue();
}
private bool ApplyOperator(object propertyValue, EnumOperator op, object value)
{
switch (op)
{
case EnumOperator.Equals:
return propertyValue.Equals(value);
//TODO other operators
default:
throw new UnsupportedEnumException(op);
}
}
(的优化将是仰望PropertyInfo
一次循环外)。