0

私は次の方法を持っています:

private List<T> GetEntities<T>(T entity) {
    // ...
}

public virtual List<T> Find<T>(Predicate<T> match) {
    // ...
}

ラムダ式の値を取得するにはどうすればよいPredicate<T>ですか?

私は次のようなことをしたいと思います:

var result = Find<MyObject>(o => o.Name == "Something")

そして、私がするFind方法では:

public virtual List<T> Find<T>(Predicate<T> match) {
    // ...
    string name = myObj.Name  // equals to "Something"        
    return GetEntities<T>(myObj) //Note that here is my object with the parameters passed via lambda
    // ...
}

これどうやってするの?

編集: MyObjectを受け取るメソッドはすでに存在します。エンティティをフィルタリングするためだけにオブジェクトをインスタンス化せずに、ラムダ式を使用できるメソッドが必要です。FuncとPredicateのどちらを使用するかわかりません

編集2:要求に応じて、これが私が達成することの具体的な例です:

現在、特定のフィルターを使用してオブジェクトを取得する場合は、次を使用します。

Person p = new Person() { Name = "John" };
var result = GetEntities<Person>(p);

私がしたいこと:

var result = Find<Person>(p => p.Name = "John");

ただし、内部的には前のメソッドを引き続き使用したいので、式をオブジェクトに変換してから、GetEntities<Person>(p)

結論: 私は述語とFuncのものと本当に多くの混乱をしました。それらをオブジェクトとして扱うことができると思いましたが、それは表現であり、私の質問はこれらの要素の概念から完全に外れました。

4

4 に答える 4

3

署名と使用法から、次のコードが私があなたのために推測したものです。コンパイルされますが、使用するには正しくありません。

  • クラス

    public partial class MyObject {
        public String Name;
    }
    
    public partial class MyGeneric<U> where U: MyObject {
        private List<T> GetEntities<T>(T entity) where T: U {
            throw new NotImplementedException(); // not implemented yet
        }
    
        public virtual List<T> Find<T>(Predicate<T> match) where T: U {
            foreach(var myObj in m_List)
                if(match(myObj as T)) {
                    // ...
                    var name=myObj.Name;
                    // ...
                    return this.GetEntities(myObj as T);
                }
    
            return new List<T>();
        }
    
        List<U> m_List;
    }
    
  • テスト

    var myGeneric=new MyGeneric<MyObject>();
    var result=myGeneric.Find<MyObject>(o => o.Name=="Something");
    

これが私が伝えたいことです:

  1. あなたはジェネリックを誤解するかもしれません。

    クラスMyGenericとこれらの2つのメソッドを見ると、すべてに制約があります。コードの使用法から、これらの制約なしではほとんど実行できませんが、これは不必要に複雑です。

  2. Predicate<T>ラムダ式やラムダ式を誤解している可能性があります

    の定義Predicate<T>

    public delegate bool Predicate<T>(T obj);
    

    つまり、それは代理人です。デリゲートへobjの引数パスです。objしたがって、別のコンテキストで取得することはできません。しかし、あなたは次のようなことをすることができます

    MyObject x;
    var myGeneric=new MyGeneric<MyObject>();
    var result=myGeneric.Find<MyObject>(o => (x=o).Name=="Something");
    

    ここでは、をx参照してoいますが、あなたのFind方法では、そうすることはおそらくありません。したがって、に渡されるオブジェクトはPredicate<T>、アクセスできる場所にすでに存在している必要があります。そうでない場合は、アクセスできません。

コンパイル可能なステートメントの構文が何を実行でき、場合によっては機能するかを示すコードを投稿します。しかし、私は強くこのようなことをしないことをお勧めします。

于 2013-03-06T22:25:28.190 に答える
0

私があなたの質問を正しく理解している場合、2番目の方法は次のようになります。

public virtual List<T> Find<T>(Expression<Predicate<T>> match)
{
    return _myCollection.Where(match).ToList();
}

次に、ラムダ式をメソッドに渡して、一致のリストを取得します。

于 2013-03-06T20:31:29.213 に答える
0

これを試して

public virtual List<T> Find<T>(Func<T,bool> match)
{
   return lst.Where(match).ToList();
}
于 2013-03-06T20:47:54.543 に答える
0

あなたの例では、これは適切です:

public virtual List<T> Find(T myObj)
{
    return GetEntities(myObj);
}

IEnumerableからアイテムをフィルタリングする場合にのみ、述語()を渡す必要がありFunc<T, bool>、質問にIEnumerableがありません。IEnumerableがある場合は、次のようにします。

private IEnumerable<T> _list;
public virtual List<T> Find(Func<T, bool> predicate)
{
    T myObj = _list.FirstOrDefault(predicate);
    return GetEntities(myObj);
}

少し拡張すると、あなたo => o.Name == "Something"は次のようになります。

private bool Filter(MyObject enumeratedObject)
{
    return enumeratedObject.Name == "Something";
}

列挙が行われ、リストの各要素に対してFilter(...)の呼び出しが開始されるまで、値は含まれません。

于 2013-03-06T21:28:23.553 に答える