2013-03-06 73 views
0

我有以下幾種方法:如何獲得Lambda表達式上的謂詞<T>值?

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

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

我怎樣才能在Predicate<T> lambda表達式的值是多少?

我想這樣做:

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,我只是想,我可以使用lambda表達式,而不實例化對象只是過濾實體的方法等。不知道如果我使用的函數功能或謂語

編輯2:按照要求,這裏是什麼,我會達到一個具體的例子:

目前,當我想要檢索與特定的過濾器的對象,我用:

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

我想做什麼:

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

然而在內部想繼續使用以前的方法,我只想調高表達成一個對象,然後使用GetEntities<Person>(p)

結論: 我做了一個非常很多困惑與謂詞和函數功能的。我認爲我可以把它們當作對象,但是是表達式,我的問題完全落後於這些元素的概念。

+0

'match'沒有任何與之相關的值。 – 2013-03-06 19:59:28

+4

「謂語的價值」是什麼意思?你有什麼?任何你想使用'Predicate '的原因,而不僅僅是'Func '和Enumerable.Where? – 2013-03-06 19:59:34

+0

你究竟是什麼意思?我怎樣才能得到Predicate的值? – 2013-03-06 20:00:22

回答

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. 你可能誤解的Predicate<T>也lambda表達式

    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>,必須已經在某處你可以訪問它,否則你永遠不會。

我發佈的代碼演示了您可以執行的語句的可編譯語法,甚至可能有效。但我建議不要做這樣的事情。

+0

謝謝。事實上,我對謂詞和代表做了很多混淆。你的例子很簡單明瞭! – GuFigueiredo 2013-03-07 12:57:37

0

如果我明白你的問題的權利,你的第二個方法應該是這樣的:

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

然後,您可以通過lambda表達式到方法,並得到匹配的列表回來。

+0

不,我想獲得傳遞給lambda表達式的值並使用它們調用具有相同返回類型的另一個方法 – GuFigueiredo 2013-03-06 20:40:17

0

試試這個

public virtual List<T> Find<T>(Func<T,bool> match) 
{ 
    return lst.Where(match).ToList(); 
} 
0

在您的例子,這將是正確的:

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

你需要傳遞謂詞(Func<T, bool>)假如你想從IEnumerable的篩選項目,你不在你的問題中沒有任何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"; 
} 

它不包含任何價值,除非發生了列舉,並開始調用過濾器(... )爲列表的每個元素。

+0

這不完全是我需要的。我不會使用表達式來過濾List。我想用表達式將它轉換爲一個對象。我只需要表達式的值... – GuFigueiredo 2013-03-06 22:05:51

+0

然後再讀我的答案。表達式基本上是一種方法,它沒有任何價值。你在上面的「過濾器」功能中有什麼價值嗎?不,你對錶達方式有誤解。 – Nenad 2013-03-06 22:23:29

+0

是的,現在我明白了。 – GuFigueiredo 2013-03-07 13:03:27

相關問題