2010-12-21 24 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); 
     }