1

こんにちは、ジェネリック クラスにフィルターを適用する必要があります。サンプルクラスは以下の通り

public class Sample<T>
{
    List<T> sourceList = new List<T>();

    public void applyFilter(string propertyName , EnumOperator operator , object value)
    {

    }
}

ここで、linq または動的 linq を使用してフィルターを実装したいのですが、この機能を実装するための前向きな方向性が得られません。

この機能を実装できるように、前向きな方向性を教えてください。

ありがとう。

4

4 に答える 4

3

ソースを変更する代わりに、フィルター処理されたリストを返すことをお勧めします。また、文字列 "operator" は 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 のメソッドを使用してほとんどすべてをフィルター処理できます。

于 2012-12-28T09:59:06.373 に答える
2

動的式 (文字列として) を使用してクエリを実行するには、Microsoft のScott GuによるDynamic LINQを使用できます。

サンプル

次の操作をサポートしています
1. Select
2. Where
3. OrderBy
4. Skip
5. Take
6. GroupBy

上記のすべての操作は、文字列をパラメーターとして受け取ります。

また、非常に使いやすい小さな式言語 (セレクター/述語/などを構築するため) も備えています。

例:

var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");  
于 2012-12-28T10:18:30.070 に答える
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 を drpCountryDropDownListという名前のコントロールにバインドします。

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 つの項目しかありません

米国
英国

今、あなたのケースにこれらのテクニックを適用してください..

于 2012-12-28T10:10:23.493 に答える
0

リフレクションを使用してプロパティ値を取得できます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、ループの外側で once を検索することです。)

于 2012-12-28T10:01:27.220 に答える