gpt4 book ai didi

c# - HashSet.CreateSetComparer 的用法示例

转载 作者:太空狗 更新时间:2023-10-30 01:03:38 25 4
gpt4 key购买 nike

我知道 HashSet<T>.SetEquals方法,但应该何时以及如何CreateSetComparer被使用?

documentation声明:“仅在一个级别检查相等性;但是,您可以将其他级别的比较器链接在一起以执行更深入的相等性测试”

什么是一个简单的例子?

特别是,如果我比较的集合中的每个项目也包含一个 HashSet ,那么 CreateSetComparer 的正确用法是什么? ?

这是我的起点。我想知道 CreateSetComparer 是否方法是否适用以及如何正确使用:

public class Foo : IEquatable<Foo>
{
public string Label { get; set; }
public string Value { get; set; }
public override string ToString() {return String.Format("{0}:{1}", Label, Value); }

// assume for this example that Label and Value are immutable once set;
public override int GetHashCode(){ return ToString().GetHashCode(); }
// simplified equality check; assume it meets my needs for this example;
public bool Equals(Foo other){ return String.Equals(this.ToString(), other.ToString()); }
}

public class FooGroup : IEquatable<FooGroup>
{
public int GroupIndex {get; set;}
public HashSet<Foo> FooCollection {get; set;}

// -----------------------------
// Does HashSet.CreateSetComparer somehow eliminate or simplify the following code?
// -----------------------------
public override int GetHashCode()
{
int hash = GroupIndex;
foreach(Foo f in FooCollection)
hash = hash ^ (f.GetHashCode() & 0x7FFFFFFF);
return hash;
}

public bool Equals(FooGroup other)
{
// ignore missing null checks for this example
return this.GroupIndex == other.GroupIndex && this.FooCollection.SetEquals(other.FooCollection);
}
}

public class GroupCollection : IEquatable<GroupCollection>
{
public string CollectionLabel {get; set;}
public HashSet<FooGroup> AllGroups {get; set;}

// -----------------------------
// Does HashSet.CreateSetComparer somehow eliminate or simplify the following code?
// -----------------------------
public override int GetHashCode()
{
int hash = CollectionLabel.GetHashCode();
foreach(FooGroup g in AllGroups)
hash = hash ^ (g.GetHashCode() & 0x7FFFFFFF);
return hash;
}

public bool Equals(GroupCollection other)
{
// ignore missing null checks for this example
return String.Equals(this.CollectionLabel, other.CollectionLabel) && this.AllGroups.SetEquals(other.AllGroups);
}
}

忽略关于系统设计等的争论,一个简化的用例是:假设我提取了一组看起来像这样的复杂数据:

var newSetA = new GroupCollection{ ... }
var oldSetA = new GroupCollection{ ... }

我只想检查:

if (newSetA.Equals(oldSetA))
Process(newSetA);

最佳答案

让我们从“CreateSetComparer 什么时候有用”这个问题开始吧?你已经有了一个很好的想法:

In particular, if each item in the sets I am comparing also contains a HashSet , what would be the correct usage of CreateSetComparer?

好吧,例如,下一个示例演示了 HashSet 使用其默认比较器(仅通过引用进行比较)时的默认行为:

var set1 = new HashSet<HashSet<int>>{
new HashSet<int>{2,3,4},
new HashSet<int>{7,8,9}
};
var set2 = new HashSet<HashSet<int>>{
new HashSet<int>{2,3,4},
new HashSet<int>{7,8,9},
};

set1.SetEquals(set2).Dump(); // false :-(
set1.SequenceEqual(set2).Dump(); // false
set1.SequenceEqual(set2, HashSet<int>.CreateSetComparer()).Dump(); // true

也可以将 CreateSetComparerSetEquals 一起使用,如下所示:

// the order of elements in the set has been change.
var set1 = new HashSet<HashSet<int>>(HashSet<int>.CreateSetComparer()){
new HashSet<int>{2,3,4},
new HashSet<int>{7,8,9}
};
var set2 = new HashSet<HashSet<int>>{
new HashSet<int>{7,8,9},
new HashSet<int>{2,3,4},
};

set1.SetEquals(set2).Dump(); // true :-)
set1.SequenceEqual(set2).Dump(); // false
set1.SequenceEqual(set2, HashSet<int>.CreateSetComparer()).Dump(); // false

这是通常的用法,但是 CreateSetComparer 提供了您可以利用的 GetHashCode,尽管这不一定比您已经做的更短/更清晰。

// -----------------------------
// Does HashSet.CreateSetComparer somehow eliminate or simplify the following code?
// -----------------------------
private IEqualityComparer<HashSet<FooGroup>> _ecomparer =
HashSet<FooGroup>.CreateSetComparer();
public override int GetHashCode()
{
int hash = CollectionLabel.GetHashCode();
hash ^= _ecomparer.GetHashCode(AllGroups);
return hash;
}

关于c# - HashSet<T>.CreateSetComparer 的用法示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27384532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com