Linq is awesome and always makes tasks easier! Here is a great tip that you might not know about.
Today I needed to compare two generic lists… SequenceEqual() to the rescue. To show how it works, here is some sample code:
[Test] public void SuccessfullyMatchesTwoListsOfInts() { List<int> ints1 = new List<int>(); ints1.Add(1); ints1.Add(2); ints1.Add(3); List<int> ints2 = new List<int>(); ints2.Add(1); ints2.Add(2); ints2.Add(3); Assert.That(ints1.SequenceEqual(ints2), Is.True); }
SequenceEqual loops through the 2 lists and compares each item to make sure they match. Just for kicks I put it through the paces. Here are some other unit tests that I wrote. This helps show what you can do:
using System.Collections.Generic; using System.Linq; using NUnit.Framework; namespace SequenceEqual { [TestFixture] public class SequenceEqualTests { [Test] public void SuccessfullyMatchesTwoListsOfInts() { List<int> ints1 = new List<int>(); ints1.Add(1); ints1.Add(2); ints1.Add(3); List<int> ints2 = new List<int>(); ints2.Add(1); ints2.Add(2); ints2.Add(3); Assert.That(ints1.SequenceEqual(ints2), Is.True); } [Test] public void SuccessfullyFailsTwoListsOfInts() { // these two don't match! List<int> ints1 = new List<int>(); ints1.Add(1); ints1.Add(2); ints1.Add(3); List<int> ints2 = new List<int>(); ints2.Add(1); ints2.Add(4); ints2.Add(3); Assert.That(ints1.SequenceEqual(ints2), Is.False); } [Test] public void SuccessfullyFailsTwoListsOfIntsOutOfOrder() { // these two don't match. They have the same contents but the order is changed. List<int> ints1 = new List<int>(); ints1.Add(3); ints1.Add(2); ints1.Add(1); List<int> ints2 = new List<int>(); ints2.Add(1); ints2.Add(2); ints2.Add(3); Assert.That(ints1.SequenceEqual(ints2), Is.False); } [Test] public void SuccessfullyFailsTwoListsOfStrings() { // these two lists of strings don't match List<string> strings1 = new List<string>(); strings1.Add("one"); strings1.Add("two"); strings1.Add("three"); List<string> strings2 = new List<string>(); strings2.Add("one"); strings2.Add("lasjdflkajsdf"); strings2.Add("three"); Assert.That(strings1.SequenceEqual(strings2), Is.False); } [Test] public void SuccessfullyMatchesTwoListsOfStrings() { // two matching lists of strings. List<string> strings1 = new List<string>(); strings1.Add("one"); strings1.Add("two"); strings1.Add("three"); List<string> strings2 = new List<string>(); strings2.Add("one"); strings2.Add("two"); strings2.Add("three"); Assert.That(strings1.SequenceEqual(strings2), Is.True); } [Test] public void SuccessfullyMatchesTwoListsOfObjects() { // works for objects too. List<TestObject> objects1 = new List<TestObject>(); objects1.Add(new TestObject { Property1 = "1" }); objects1.Add(new TestObject { Property1 = "2" }); objects1.Add(new TestObject { Property1 = "3" }); Assert.That(objects1.SequenceEqual(objects1), Is.True); } [Test] public void SuccessfullyFailsTwoListsOfObjects() { // these two lists of objects may "look" the same, but they aren't // the same object (reference equals!) List<TestObject> objects1 = new List<TestObject>(); objects1.Add(new TestObject { Property1 = "1" }); objects1.Add(new TestObject { Property1 = "2" }); objects1.Add(new TestObject { Property1 = "3" }); List<TestObject> objects2 = new List<TestObject>(); objects2.Add(new TestObject { Property1 = "1" }); objects2.Add(new TestObject { Property1 = "2" }); objects2.Add(new TestObject { Property1 = "3" }); Assert.That(objects1.SequenceEqual(objects2), Is.False); } [Test] public void SuccessfullyMatchesTwoListsOfObjectsWithCustomComparer() { // here I use a custom comparer to see if the // two lists of objects have the same content. List<TestObject> objects1 = new List<TestObject>(); objects1.Add(new TestObject { Property1 = "1" }); objects1.Add(new TestObject { Property1 = "2" }); objects1.Add(new TestObject { Property1 = "3" }); List<TestObject> objects2 = new List<TestObject>(); objects2.Add(new TestObject { Property1 = "1" }); objects2.Add(new TestObject { Property1 = "2" }); objects2.Add(new TestObject { Property1 = "3" }); Assert.That(objects1.SequenceEqual(objects2, new TestObjectComparer()), Is.True); } [Test] public void SuccessfullyFailsTwoListsOfObjectsWithCustomComparer() { // making sure the custome comparer fails when they don't match List<TestObject> objects1 = new List<TestObject>(); objects1.Add(new TestObject { Property1 = "1" }); objects1.Add(new TestObject { Property1 = "2" }); objects1.Add(new TestObject { Property1 = "3" }); List<TestObject> objects2 = new List<TestObject>(); objects2.Add(new TestObject { Property1 = "1" }); objects2.Add(new TestObject { Property1 = "asdfsadf" }); objects2.Add(new TestObject { Property1 = "3" }); Assert.That(objects1.SequenceEqual(objects2, new TestObjectComparer()), Is.False); } } public class TestObject { public string Property1 { get; set; } } public class TestObjectComparer : IEqualityComparer<TestObject> { public bool Equals(TestObject x, TestObject y) { return (x.Property1 == y.Property1); } public int GetHashCode(TestObject obj) { return obj.GetHashCode(); } } }
Today I needed to compare to generic lists. I guessed that Linq would provide a way to do this and sure enough it did: SequenceEqual() to the rescue. To show how it work