C# 一个以列表为键的字典是如何工作的?

C# 一个以列表为键的字典是如何工作的?,c#,.net,C#,.net,我正在处理遗留代码,我看到一个字典,它的键是一个对象列表 var myCrazyDictionary = new Dictionary<List<MyKeyObject>, List<MyValueObject>>(); var myCrazyDictionary=新字典(); 这样一本字典的作用是什么?你知道,因为引用类型 它能像这样神奇地工作吗 // ???? myCrazyDictionary.Add(new List<MyKeyObject&

我正在处理遗留代码,我看到一个字典,它的键是一个对象列表

var myCrazyDictionary = new Dictionary<List<MyKeyObject>, List<MyValueObject>>();
var myCrazyDictionary=新字典();
这样一本字典的作用是什么?你知道,因为引用类型

它能像这样神奇地工作吗

// ????
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;
/????
添加(新列表{new MyKeyObject{Key1=“1”,Key2=2}},新列表{new MyValueObject{Value=“!”});
// ???????????
var result=myCrazyDictionary[new List{new MyKeyObject{Key1=“1”,Key2=2}];
//这会保持值:“!”还是崩溃或其他什么?
var byWhatBlackMagic=结果[0]。值;

这将与您为添加和检索创建了一个字典
字典
和一个
新对象()
一样<代码>列表不会覆盖
等于(对象)
GetHashCode()
,因此它只使用默认行为,仅比较对象引用。它不会查看列表内部以进行比较。因此,当您尝试执行
myCrazyDictionary[new List{…}]
时,您的示例将抛出一个
KeyNotFoundException
,因为您正在创建一个“新对象”,而该新对象不在字典中(因为您刚刚创建了它)

您可以获得所需的功能,只需制作一个自定义的
IEqualityComparer
,并将其传递给字典的构造函数


注意如果你做了一个自定义比较器,你的
列表
中没有任何东西与你的自定义
相等(列表,列表)
或者你的自定义
。GetHashCode(列表)
可以在它作为键滚动时更改,或者你会破坏
字典
的内部逻辑,我验证了
List
没有重写
Equals
GetHashCode
@minghan,您也可以通过检查,如果重写了一个方法,它会说“(重写Object.Equals(Object)”,如果没有重写,它会说“(继承自Object.)”(有关重写的示例,请参阅)。检查源代码是一个“实现细节”,可能会发生更改,MSDN上的任何内容都是一个“合同”,并且行为保证在.NET版本之间不会更改,除非在Remarks中有说明。下载时,将代码放在那里,然后自己测试。或者Visual Studio 2015有一个集成的REPL。您可能应该编写自己的类来保存键值。确保键不发生更改(理想情况下,将其设置为不可变类型)。