Hi I have to apply filter on generic class. The sample class is as follows
public class Sample
{
List sourceList = new List();
I would recommend returning an filtered list instead of modifying the source, and also the string "operator" is a C# keyword, so the signature of the method could be:
public List<T> ApplyFilter(string propertyName, EnumOperator operatorType, object value)
{
....
}
where I assume that the EnumOperator
is an enum
with values like this:
public enum EnumOperator
{
Equal,
NotEqual,
Bigger,
Smaller
}
and that you have some way to check if for an operator a value passes or fails the test, something along the lines of:
public static class OperatorEvaluator
{
public static bool Evaluate(EnumOperator operatorType, object first, object second)
{
...
}
}
Given that, you can do something like:
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;
}
That said, you can always use LINQ's methods to filter almost anything without resorting to reflection.
You can use Reflection for retrieving the property value and you can use a simple switch
statement upon the operator to perform the filtering:
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);
}
}
(An optimization would be to look up the PropertyInfo
once outside of the loop.)
To query with dynamic expression (as string), you can use Dynamic LINQ by Scott Gu of Microsoft.
Samples
It supports following operations
1. Select
2. Where
3. OrderBy
4. Skip
5. Take
6. GroupBy
All above operations take string as parameter.
It also has small expression language (to build selectors/predicates/etc) which is very easy to use.
Example:
var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");
Here I give you a sample example how to implement filtering using LINQ on List<T>
items..
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; }
}
}
Now, lets create a list of objects based on class clsCountry
and store them in a List<T>
object.
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"));
Next, we shall bind the List<T>
object lstCountry to a DropDownList
control named drpCountry as like as:
drpCountry.DataSource = lstCountry;
drpCountry.DataValueField = "CountryCode";
drpCountry.DataTextField = "CountryName";
drpCountry.DataBind();
Now, use LINQ to filter data from the lstCountry object and bind the filtered list to the dropdown control 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();
Now the dropdown control will have only 2 items
United States
United Kingdom
Now apply those techniques on your case..