比较两个List <string>是否相等

除了一个接一个地逐步遍历元素之外,我如何比较两个string列表是否相等(在.NET 3.0中):

这失败了:

// Expected result. List<string> expected = new List<string>(); expected.Add( "a" ); expected.Add( "b" ); expected.Add( "c" ); // Actual result actual = new List<string>(); actual.Add( "a" ); actual.Add( "b" ); actual.Add( "c" ); // Verdict Assert.IsTrue( actual == expected ); 

提前致谢

许多testing框架提供了一个CollectionAssert类:

 CollectionAssert.AreEqual(expected, actual); 

如MStesting

尝试以下

 var equal = expected.SequenceEqual(actual); 

testing版本

 Assert.IsTrue( actual.SequenceEqual(expected) ); 

SequenceEqual扩展方法将比较集合中的元素以便相等。

请参阅http://msdn.microsoft.com/en-us/library/bb348567(v=vs.100).aspx

你总是可以自己编写所需的函数:

 public static bool ListEquals<T>(IList<T> list1, IList<T> list2) { if (list1.Count != list2.Count) return false; for (int i = 0; i < list1.Count; i++) if (!list1[i].Equals(list2[i])) return false; return true; } 

并使用它:

 // Expected result. List<string> expected = new List<string>(); expected.Add( "a" ); expected.Add( "b" ); expected.Add( "c" ); // Actual result actual = new List<string>(); actual.Add( "a" ); actual.Add( "b" ); actual.Add( "c" ); // Verdict Assert.IsTrue( ListEquals(actual, expected) ); 

我注意到没有人实际告诉你为什么你的原始代码不起作用。 这是因为==运算符通常testing引用相等 (即,如果两个实例指向内存中的同一个对象),除非运算符已被重载 。 List<T>没有定义一个==运算符,因此使用基本引用equals实现。

正如其他海报所表明的那样,你通常必须通过元素来检验“收集平等”。 当然,你应该使用由用户DreamWalkerbuild议的优化,它首先testing集合的计数之前,通过它们。

如果订单很重要:

 bool equal = a.SequenceEquals(b); 

如果顺序无关紧要:

 bool equal = a.Count == b.Count && new HashSet<string>(a).SetEquals(b); 

你可以这样写一个扩展方法:

 public static class ListExtensions { public static bool IsEqual<T>(this IList<T> list,IList<T> target, IComparer<T> comparer) where T:IComparable<T> { if (list.Count != target.Count) { return false; } int index = 0; while (index < list.Count && comparer.Compare(list[index],target[index]) == 0) { index++; } if (index != list.Count) { return false; } return true; } } 

并称之为如此:

 List<int> intList = new List<int> { 1, 234, 2, 324, 324, 2 }; List<int> targetList = new List<int> { 1, 234, 2, 324, 324 }; bool isEqual = intList.IsEqual(targetList, Comparer<int>.Default); 

编辑:更新代码使用静态方法,因为OP是使用.NET 3.0

 public static bool IsEqual<T>(IList<T> sourceList, IList<T> targetList, IComparer<T> comparer) where T : IComparable<T> { if (sourceList.Count != targetList.Count) { return false; } int index = 0; while (index < sourceList.Count && comparer.Compare(sourceList[index], targetList[index]) == 0) { index++; } if (index != sourceList.Count) { return false; } return true; } 

客户:

  bool isEqual = IsEqual(intList,targetList, Comparer<int>.Default); 

使用Linq并将代码编写为扩展方法:

 public static bool EqualsOtherList<T>(this List<T> thisList, List<T> theOtherList) { if (thisList == null || theOtherList == null || thisList.Count != theOtherList.Count) return false; return !thisList.Where((t, i) => !t.Equals(theOtherList[i])).Any(); } 

虽然它迭代了集合,但是我创build的这个扩展方法并不要求两个列表的顺序相同,只要Equals方法被覆盖,它也可以处理复杂的types。

以下两个列表将返回true:

 List<string> list1 = new List<string> { { "bob" }, { "sally" }, { "john" } }; List<string> list2 = new List<string> { { "sally" }, { "john" }, { "bob" } }; 

方法:

 public static bool IsEqualTo<T>(this IList<T> list1, IList<T> list2) { if (list1.Count != list2.Count) { return false; } List<T> list3 = new List<T>(); foreach (var item in list2) { list3.Add(item); } foreach (var item in list1) { int index = -1; for (int x = 0; x < list3.Count; x++) { if (list3[x].Equals(item)) { index = x; } } if (index > -1) { list3.RemoveAt(index); } else { return false; } } return !list3.Any(); }