Есть полезный оператор LINQ, называемый SequenceEqual()
, который сравнивает две последовательности на равенство. SequenceEqual()
просматривает любые две последовательности IEnumerable<>
и проверяет, имеют ли они одинаковое число элементов и что элементы с одинаковым индексом равны (с помощью сравнения по умолчанию равенство). Однако, поскольку у вас есть вложенные коллекции, вам необходимо расширить концепцию равенства, чтобы применить их и к ним. К счастью, существует перегрузка, которая позволяет вам предоставить свой собственный объект IEqualityComparer<>
.
Поскольку неудобно постоянно определять класс для обеспечения семантики равенства, я написал общее расширение, которое позволяет вам вместо этого использовать делегат. Давайте посмотрим на код:
public static class ComparerExt
{
private class GenericComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> m_EqualityFunc;
public GenericComparer( Func<T,T,bool> compareFunc )
{
m_EqualityFunc = compareFunc;
}
public bool Equals(T x, T y)
{
return m_EqualityFunc(x, y);
}
}
// converts a delegate into an IComparer
public static IEqualityComparer<T> AreEqual<T>( Func<T,T,bool> compareFunc )
{
compareFunc.ThrowIfNull("compareFunc");
return new GenericComparer<T>(compareFunc);
}
}
Теперь мы можем легко сравнить две последовательности:
Assert.IsTrue(
// check that outer sequences are equivalent...
a1.SequenceEqual( a2,
// define equality as inner sequences being equal...
ComparerExt.AreEqual( (a,b) => a.SequenceEqual(b) ) );