c# - 使用类与结构作为字典键

标签 c# class dictionary struct equality

假设我有以下类和结构定义,并将它们分别用作字典对象中的键:

public class MyClass { }
public struct MyStruct { }

public Dictionary<MyClass, string> ClassDictionary;
public Dictionary<MyStruct, string> StructDictionary;

ClassDictionary = new Dictionary<MyClass, string>();
StructDictionary = new Dictionary<MyStruct, string>();

为什么会这样:

MyClass classA = new MyClass();
MyClass classB = new MyClass();
this.ClassDictionary.Add(classA, "Test");
this.ClassDictionary.Add(classB, "Test");

但这会在运行时崩溃:

MyStruct structA = new MyStruct();
MyStruct structB = new MyStruct();
this.StructDictionary.Add(structA, "Test");
this.StructDictionary.Add(structB, "Test");

它表示 key 已经存在,正如预期的那样,但仅适用于结构。该类将其视为两个单独的条目。我认为这与作为引用与值(value)的数据有关,但我想要更详细的解释原因。

最佳答案

Dictionary<TKey, TValue>使用 IEqualityComparer<TKey>用于比较键。如果在构造字典时没有显式指定比较器,它将使用 EqualityComparer<TKey>.Default 。 .

因为MyClass也不MyStruct实现 IEquatable<T> ,默认的相等比较器将调用 Object.EqualsObject.GetHashCode用于比较实例。 MyClass源自 Object ,因此实现将使用引用相等性进行比较。 MyStruct另一方面来自 System.ValueType (所有结构的基类),所以它将使用 ValueType.Equals 用于比较实例。此方法的文档说明如下:

The ValueType.Equals(Object) method overrides Object.Equals(Object) and provides the default implementation of value equality for all value types in the .NET Framework.

If none of the fields of the current instance and obj are reference types, the Equals method performs a byte-by-byte comparison of the two objects in memory. Otherwise, it uses reflection to compare the corresponding fields of obj and this instance.

异常发生是因为 IDictionary<TKey, TValue>.Add 抛出 ArgumentException如果“具有相同键的元素已存在于[字典]中。”使用结构时,由 ValueType.Equals 完成的逐字节比较导致两个调用都尝试添加相同的 key 。

关于c# - 使用类与结构作为字典键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16472159/

相关文章:

Javascript - 如何更改类的父类?

python - 如何在发布数据python中接收字典

c# - 是否有任何实现可以通过键删除并同时获取值?

c# - 如何在 C# 中添加自定义标签将 JSON 转换为 XML

c# - 如何在C#中比较两个波形的相似性?

c# - Microsoft Service Fabric 有状态服务无法启动

php - PHP 中的类插件?

c# - 如何在 Visual Studio 2013 上恢复关闭的表单

jquery - 如何使用 jQuery 过滤不需要的元素

c# - Int32.ToString() 太慢