Intersect extension method, case sensitivity not working
I am trying to compare the contents of 2 collections in a unit test in .NET using MSTEST. To make things simple, instead of having to .Sort() and then loop through the collection and compare items one at a time, I've found the new and very cool .Intersect Extension method.
It seems to work great by doing:
Assert.AreEqual(expected.Count, actual.Intersect(expected).Count)
However, now that I have a test which needs to be case-sensitive, it breaks. I've tried sending Intersect's second parameter StringComparer.Ordinal,StringComparer.InvariantCulture, and StringComparer.CurrentCulture... no luck..
Anyone experience this before?
thanks!
EDIT: here is the data:
Actual:
(0) "FOO" String
(1) "foo" String
(2) "Foo" String
(3) "fOo" String
(4) "foO" String
(5) "BAR" String
(6) "BAR" String
(7) "BAZ" String
(8) "baz" String
(9) "foo" String
Expected:
(0) "FOO" String
(1) "foo" String
(2) "Foo" String
(3) "fOo" String
(4) "foO" String
(5) "BAR" String
(6) "BAR" String
(7) "BAZ" String
(8) "baz" String
(9) "foo" String
actual.Intersect(expected, StringComparer.CurrentCulture)
(0) "FOO" String
(1) "foo" String
(2) "Foo" String
(3) "fOo" String
(4) "foO" String
(5) "BAR" String开发者_开发知识库
(6) "BAZ" String
(7) "baz" String
It seems to be removing a matching duplicate 'foo', and a matching duplicate 'BAZ'. Perhaps there is a better way to assert collections are matching?
_EDIT2: I think Intersect() removes duplicates, which is why this is breaking. I Found the CollectionAssert Class. This is exactly what I needed! Thanks! _
For testing purposes use CollectionAssert.AreEqual(actual, expected)
You were looking for SequenceEqual, not Intersect. Intersect returns the intersection of two sequences, ie. the items shared between them. Using Intersect on { 1, 2, 3 } and { 3, 4, 5 } would return 3. SequenceEqual would return false.
Had you not found CollectionAssert you could've used:
Assert.IsTrue(actual.SequenceEqual(expected))
Implement an IEqualityComparer like so:
Class StringCaseInsensitiveComparer
Implements IEqualityComparer(Of String)
Public Function Equals(ByVal s1 As String, ByVal s2 As String) As Boolean
Return s1.ToLower() = s2.ToLower()
End Function
Public Function GetHashCode(ByVal s As String) As Integer
Return s.GetHashCode()
End Function
End Class
Then, call this overload of Intersect:
Dim first As IEnumerable(Of TSource)
Dim second As IEnumerable(Of TSource)
Dim comparer As IEqualityComparer(Of TSource)
Dim returnValue As IEnumerable(Of TSource)
passing it an instance of the comparer that you just made.
精彩评论