【发布时间】:2021-08-22 01:23:27
【问题描述】:
在较新版本的 NUnit 中,显然可以比较嵌套集合,正如this answer 所说。但是,这似乎不适用于嵌套的HashSets。考虑:
var a1 = new Dictionary<string, HashSet<string>> {
{ "a", new() { "b", "c" } },
{ "b", new() { "c" } },
{ "c", new() { } },
};
var a2 = new Dictionary<string, HashSet<string>> {
{ "c", new() { } },
{ "a", new() { "b", "c" } },
{ "b", new() { "c" } },
};
CollectionAssert.AreEqual(a1, a2);
这通过了,但是如果我稍微更改向集合添加值的顺序(或做任何改变其中一个集合的迭代顺序的事情):
var a1 = new Dictionary<string, HashSet<string>> {
{ "a", new() { "b", "c" } },
{ "b", new() { "c" } },
{ "c", new() { } },
};
var a2 = new Dictionary<string, HashSet<string>> {
{ "c", new() { } },
{ "a", new() { "c", "b" } },
{ "b", new() { "c" } },
};
CollectionAssert.AreEqual(a1, a2);
我预计它仍然可以通过,因为 HashSet 是无序的,但测试失败:
----> NUnit.Framework.AssertionException : Expected and actual are both <System.Collections.Generic.Dictionary`2[System.String,System.Collections.Generic.HashSet`1[System.String]]> with 3 elements
Values differ at index [0]
String lengths are both 1. Strings differ at index 0.
Expected: "b"
But was: "c"
-----------^
NUnit 似乎不知道HashSet 是无序的,但是知道Dictionary 是无序的。
所以我想我需要在某处使用HashSet<string>.CreateSetComparer()。我知道我可以指定用于与Using 进行比较的相等比较器:
Assert.That(a, Is.EqualTo(b).Using(someEqualityComparer));
但我试图提供它来比较 嵌套 集。我该怎么做?
为了避免出现 XY 问题:我的真实代码中的字典实际上代表了控制流图的边缘。实际上是Dictionary<BasicBlock, HashSet<BasicBlock>>。
【问题讨论】:
-
它把
HashSet当作一个enumerable 来处理顺序很重要,你可能已经猜到了。如果您将HashSet更改为SortedSet(例如Dictionary<string, SortedSet<string>),您可能会得到您期望的结果。但是,可能不适合您想要的。 -
@TheGeneral 感谢您提醒我
SortedSet的存在!就我而言,我可以为BasicBlock写一个IComparer,所以我认为可以使用SortedSet。不过,我仍然对更通用的解决方案持开放态度:)