2010-12-21 27 views
35

我試圖使用List<T>與我的自定義類,並且能夠使用像列表上的Contains(),Find()等方法。我想我只需要使用操作符重載==但顯然,這樣做的一個方法是使用一個委託方法與Find() ...C# - 使用列表<T>。查找()與自定義對象

注:現在,我已經超載Equals()方法獲取Contains()方法工作,但我仍然無法使Find()函數工作。

讓兩者都能工作的最佳方式是什麼?

我使用最新的C#/.NET框架版本與mono,在Linux上。

編輯:這裏是我的代碼

using System; 
namespace GuerreDesClans 
{ 
public class Reponse : IEquatable<Reponse> 
{ 
    public Reponse() 
    { 
     m_statement = string.Empty; 
     m_pointage = 0; 
    } 

    public Reponse (string statement, int pointage) 
    { 
     m_pointage = pointage; 
     m_statement = statement; 
    } 


    /* 
    * attributs privés 
    */ 

    private string m_statement; 
    private int m_pointage; 


    /* 
    * properties 
    */ 

    public string Statement { 
     get { return m_statement; } 
     set { m_statement = value; } 
    } 

    public int Pointage { 
     get { return m_pointage; } 
     set { m_pointage = value; } 
    } 

    /* 
    * Equatable 
    */ 

    public bool Equals (Reponse other) 
    { 
     if (this.m_statement == other.m_statement) 
      return true; 
     else 
      return false; 
    } 
} 

}

,我想如何使用find()函數來搜索我的效應初探對象...

list.find("statement1"); // would return a Reponse object 
+1

你是如何調用'Find'? – SLaks 2010-12-21 01:59:24

+3

顯示一些代碼。 – 2010-12-21 02:00:50

回答

49

Find()將查找與您作爲參數傳遞的謂詞相匹配的元素,因此它與Equals()或==運算符無關。

var element = myList.Find(e => [some condition on e]); 

在這種情況下,我用lambda expression作爲謂詞。你可能想閱讀這個。在Find()的情況下,你的表達式應該帶一個元素並返回一個bool。

在你的情況,這將是:

var reponse = list.Find(r => r.Statement == "statement1") 

並回答在評論的問題,這是在.NET 2.0當量,引入lambda表達式之前:

var response = list.Find(delegate (Response r) { 
    return r.Statement == "statement1"; 
}); 
+1

你能提供一個.NET 2.0的例子嗎?我在Unity3D中被困在.net 2.0 land – gman 2014-11-25 03:30:08

+0

當然,我編輯了我的答案。 – 2014-11-25 08:56:04

+0

可以認爲返回的元素是引用,並且對它的任何修改都會反映在列表中包含的相同元素上? – 2017-03-15 14:31:18

44

您可以使用使用Predicate查找如下:

list.Find(x => x.Id == IdToFind); 

這將返回列表中符合由謂詞定義的條件的第一個對象(即,在我的示例中,我正在查找具有ID的對象)。

+0

這種技術叫做什麼? – Pacane 2010-12-21 02:05:34

+1

@Pacane:從msdn - 所有的lambda表達式都使用lambda運算符=>,它被讀作「去」 – 2010-12-21 02:32:32

5

以前的答案並沒有說明你已經重載了等號運算符並且正在使用它來測試所尋找的元素。在這種情況下,你的代碼應該是這樣的:

list.Find(x => x == objectToFind); 

或者,如果你不喜歡lambda語法,並有重寫的Object.Equals(對象)或已實施IEquatable <牛逼>,你可以這樣做:

list.Find(objectToFind.Equals); 
+0

這些語句都是多餘的,因爲我們已經有了objectToFind的引用。 Find()的要點是找到一個我們沒有參考的對象。使用list.Contains(objectToFind)更容易,更合理,更易讀。 – 2010-12-21 22:28:49

+1

@Greg Sansom:當然。但OP特意說他有Contains方法工作,但也想用Find。由於他重寫了Equals以比較m_statement並忽略m_pointage的值,因此Find方法不一定會返回傳遞給它的同一個實例。 Equals覆蓋的行爲可能是有問題的,但考慮到這種行爲,「list.Find(obj.Equals)」不是多餘的。 – phoog 2010-12-21 22:49:41

1

http://msdn.microsoft.com/en-us/library/x0b5b5bc.aspx

 // Find a book by its ID. 
     Book result = Books.Find(
     delegate(Book bk) 
     { 
      return bk.ID == IDtoFind; 
     } 
     ); 
     if (result != null) 
     { 
      DisplayResult(result, "Find by ID: " + IDtoFind); 
     } 
     else 
     { 
      Console.WriteLine("\nNot found: {0}", IDtoFind); 
     }