您好我必须在泛型类上应用过滤器。样本类如下
public class Sample<T>
{
List<T> sourceList = new List<T>();
public void applyFilter(string propertyName , EnumOperator operator , object value)
{
}
}
这里我想使用linq或dynamic linq实现过滤器,但是没有任何积极的方向来实现这个功能。
请给我一些积极的指导,以便我可以实现此功能。
感谢。
答案 0 :(得分:3)
我建议返回一个已过滤的列表,而不是修改源,以及字符串&#34;运算符&#34;是一个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的方法来过滤几乎任何东西而不需要反思。
答案 1 :(得分:2)
要使用动态表达式(作为字符串)进行查询,您可以使用Microsoft Dynamic LINQ的Scott Gu。
支持以下操作
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)");
答案 2 :(得分:1)
这里我给出一个示例如何使用List<T>
项目上的LINQ实现过滤。
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绑定到名为drpCountry的DropDownList
控件,如下所示:
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个项目
美国
英国
现在将这些技术应用于您的案例..
答案 3 :(得分:0)
您可以使用Reflection来检索属性值,并且可以在运算符上使用简单的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
。)