Независимо от какой-либо среды модульного тестирования, вы всегда можете перейти к перегрузке SequenceEquals<object>
, которая также требует компаратор. Это позволит вам сравнивать совершенно разные списки. Этот тест демонстрирует, как можно «обмануть» .NET, заставив его «думать», что два разнородных массива идентичны:
[Fact]
public void TestDisparateSequences()
{
var ints = new[] { 1, 3, 5, 7 };
var strings = new[] { "foo", "bar", "baz", "qux" };
Assert.True(
ints.Cast<object>().SequenceEqual(
strings.Cast<object>(),
new TrueComparer<object>()),
"Arrays look like they are equal.");
}
private class TrueComparer<T> : IEqualityComparer<T>
{
public bool Equals(T x, T y)
{
return true;
}
public int GetHashCode(T obj)
{
return 0;
}
}
Этот тест проходит, потому что TrueComparer
всегда возвращает true.
Очевидно, что это не особенно практично, но указывает на соответствующие строительные блоки, которые можно использовать для сравнения разнородных последовательностей.
SemantiComparison предоставляет класс SemanticComparer<T>
, реализующий IEqualityComparer<T>
, но он работает только со значениями одного типа. Таким образом, чтобы использовать его для сравнения разнородных последовательностей, вам нужно отобразить один из списков в последовательность другого типа.
Часто у вас уже есть такая карта, но если нет, то это хорошая мотивация для ее создания. В противном случае вы можете использовать средство семантического сопоставления, например AutoMapper.
Предположим, например, что у вас есть такой класс Foo
:
public class Foo
{
public int Number { get; set; }
public string Text { get; set; }
}
и еще один класс Bar
, очень похожий:
public class Bar
{
public int Number { get; set; }
public string Text { get; set; }
}
Теперь вы можете сравнивать foos и bar с помощью карты и SemanticComparison<Bar>
:
[Fact]
public void TestEquivalentSequences()
{
var foos = new[]
{
new Foo { Number = 42, Text = "ploeh" },
new Foo { Number = 1337, Text = "fnaah" }
};
var bars = new[]
{
new Bar { Number = 42, Text = "ploeh" },
new Bar { Number = 1337, Text = "fnaah" }
};
AutoMapper.Mapper.CreateMap<Foo, Bar>();
Assert.True(
foos.Select(AutoMapper.Mapper.Map<Bar>).SequenceEqual(
bars,
new SemanticComparer<Bar>()),
"Mapped arrays should be equivalent.");
}
Тем не менее, ваша жизнь станет намного проще, если вы придадите своим объектам структурное равенство. Этот ответ только описывает то, что возможно, а не то, что рекомендуется.
person
Mark Seemann
schedule
02.10.2015