我创建了以下代码来验证一系列“元组”的唯一性:
struct MyTuple
{
public MyTuple(string a, string b, string c)
{
ValA = a; ValB = b; ValC = c;
}
private string ValA;
private string ValB;
private string ValC;
}
...
HashSet<MyTuple> tupleList = new HashSet<MyTuple>();
如果我是正确的,我将不会在我的 HashSet
中得到两个具有相同值的元组,这要归功于我使用的是结构。如果不实现 IEquatable
或类似的东西(我没有深入研究如何做到这一点),我就无法对类进行相同的行为。
我想知道我的工作是否有问题。在性能方面,考虑到内部字符串是引用类型,我不认为使用结构会成为问题。
编辑: 我希望我的 HashSet 永远不包含两个具有相同值的字符串的元组。换句话说,我希望字符串的行为类似于值类型。
最佳答案
问题是它不会起作用。如果两个字符串是“a”,它们仍然可以是不同的引用。这种情况会破坏您的实现。
实现 Equals()
和 GetHashCode()
正确(例如,使用提供的字符串中的字符串,并注意结构中的 NULL 引用),并且可能 IEquatable<MyTuple>
让它变得更好。
编辑:默认实现明确不适合在哈希表和集合中使用。 ValueType.GetHashCode()
中明确说明了这一点实现(强调):
The GetHashCode method applies to types derived from ValueType. One or more fields of the derived type is used to calculate the return value. If you call the derived type's GetHashCode method, the return value is not likely to be suitable for use as a key in a hash table. Additionally, if the value of one or more of those fields changes, the return value might become unsuitable for use as a key in a hash table. In either case, consider writing your own implementation of the GetHashCode method that more closely represents the concept of a hash code for the type.
你应该始终执行 Equals()
和 GetHashCode()
作为“对”,这在 ValueType.Equals()
之后更加明显效率极低且不可靠(使用反射,相等比较的未知方法)。此外,当不覆盖这两个时存在性能问题(调用默认实现时结构将被装箱)。
关于具有结构和字符串的 C# HashSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2150169/