键为列表的字典的行为方式

本文关键字:方式 字典 列表 | 更新日期: 2023-09-27 18:30:47

我正在使用遗留代码,我看到一个字典,其键是对象列表...

var myCrazyDictionary = new Dictionary<List<MyKeyObject>, List<MyValueObject>>();

这样的字典是如何表现的?您知道,由于引用类型...

它像这样神奇地工作吗?

// ????
myCrazyDictionary.Add(new List<MyKeyObject> { new MyKeyObject { Key1 = "1", Key2 = 2 } }, new List<MyValueObject> { new MyValueObject { Value = "!" } });
// ???????????
var result = myCrazyDictionary[new List<MyKeyObject> { new MyKeyObject { Key1 = "1", Key2 = 2 } }];
// Will this hold the value: "!" or crash or something else?
var byWhatBlackMagic = result[0].Value;

键为列表的字典的行为方式

它就像你做了一个字典Dictionary<Object, List<MyValueObject>>并且只是对添加和检索都做了一个new Object()一样。 List<T> 不会覆盖Equals(object)GetHashCode(),因此它只使用仅比较对象引用的默认行为。它不会查看列表内部进行比较。因此,当您尝试执行myCrazyDictionary[new List<MyKeyObject> { ... }]时,您的示例将抛出KeyNotFoundException,因为您正在创建一个"新对象"并且该新对象不在字典中(因为您刚刚创建了它)。

您可以获得所需的功能,只需创建自定义IEqualityComparer<List<MyKeyObject>>并将其传递给字典的构造函数即可。

当心!如果您确实制作了自定义比较器,则在充当键的滚动时,List<MyKeyObject>中与自定义Equals(List<MyKeyObject>, List<MyKeyObject>)关联的任何内容或自定义.GetHashCode(List<MyKeyObject>)都无法更改,否则您将破坏Dictionary的内部逻辑。