如何检查对象是否已经存在于列表中

我有一个列表

List<MyObject> myList 

我将项目添加到列表,我想检查该对象是否已经在列表中。

所以在我这样做之前:

  myList.Add(nextObject); 

我想看看nextObject是否已经在列表中。

对象“MyObject”有一些属性,但比较是基于两个属性的匹配。

在添加一个新的“MyObject”到“MyObject”列表之前,做一个检查的最好方法是什么?

我认为唯一的解决scheme是从列表更改为一个字典,他们使关键字连接string的属性(这似乎有点不雅观)

任何其他更清洁的解决scheme使用列表或LINQ或其他?

这取决于具体情况的需要。 例如,字典的方法将是相当不错的,假设:

  1. 该列表相对稳定(不是很多插入/删除,哪些字典没有优化)
  2. 该列表是相当大的(否则字典的开销是毫无意义的)。

如果以上情况不适用于您的情况,请使用Any()

 Item wonderIfItsPresent = ... bool containsItem = myList.Any(item => item.UniqueProperty == wonderIfItsPresent.UniqueProperty);' 

这将枚举整个列表直到它find一个匹配,或者直到它结束。

如果可以使用这两个属性,您可以:

 bool alreadyExists = myList.Any(x=> x.Foo=="ooo" && x.Bar == "bat"); 

简单地使用Contains方法,它基于相等函数Equals

 bool alreadyExist = list.Contains(item); 

你确定在这种情况下你需要一个列表吗? 如果您使用多个项目填充列表,性能将受到myList.ContainsmyList.Any ; 运行时间将是二次的。 您可能要考虑使用更好的数据结构。 例如,

  public class MyClass { public string Property1 { get; set; } public string Property2 { get; set; } } public class MyClassComparer : EqualityComparer<MyClass> { public override bool Equals(MyClass x, MyClass y) { if(x == null || y == null) return x == y; return x.Property1 == y.Property1 && x.Property2 == y.Property2; } public override int GetHashCode(MyClass obj) { return obj == null ? 0 : (obj.Property1.GetHashCode() ^ obj.Property2.GetHashCode()); } } 

您可以按照以下方式使用HashSet:

  var set = new HashSet<MyClass>(new MyClassComparer()); foreach(var myClass in ...) set.Add(myClass); 

当然,如果MyClass这个相等的定义是“通用的”,那么就不需要编写一个IEqualityComparer实现。 你可以重载类本身的GetHashCodeEquals

还有一点要提的是,你应该确保你的平等职能是你所期望的。 您应该重写equals方法来设置对象的哪些属性必须匹配以使两个实例相等。

然后你可以做mylist.contains(item)

这是一个快速的控制台应用程序来描述如何解决您的问题的概念。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication3 { public class myobj { private string a = string.Empty; private string b = string.Empty; public myobj(string a, string b) { this.a = a; this.b = b; } public string A { get { return a; } } public string B { get { return b; } } } class Program { static void Main(string[] args) { List<myobj> list = new List<myobj>(); myobj[] objects = { new myobj("a", "b"), new myobj("c", "d"), new myobj("a", "b") }; for (int i = 0; i < objects.Length; i++) { if (!list.Exists((delegate(myobj x) { return (string.Equals(xA, objects[i].A) && string.Equals(xB, objects[i].B)) ? true : false; }))) { list.Add(objects[i]); } } } } } 

请享用!

编辑:我曾经说过:


字典解决scheme有什么不雅的地方。 这似乎对我来说是完美的,尤其是你只需要在创build字典时设置比较器。


当然,使用某些东西作为一个关键,也是一种价值。

所以我会使用一个HashSet。 如果后面的操作需要build立索引,那么当添加完成后,我会从它创build一个列表,否则,只需使用哈希集。

简单但有效

 MyList.Remove(nextObject) MyList.Add(nextObject) 

要么

  if (!MyList.Contains(nextObject)) MyList.Add(nextObject);