C# 当键本身是一种类型时,“给定的键在字典中不存在”
这是我的代码:C# 当键本身是一种类型时,“给定的键在字典中不存在”,c#,dictionary,key,C#,Dictionary,Key,这是我的代码: public class MyKeyType { public int x; public string operationStr; } private static Dictionary<MyKeyType, List<int>> m_Dict = new Dictionary<MyKeyType, List<int>> { { new MyKeyType { x = MyValsType.File, o
public class MyKeyType
{
public int x;
public string operationStr;
}
private static Dictionary<MyKeyType, List<int>> m_Dict = new Dictionary<MyKeyType, List<int>>
{
{ new MyKeyType { x = MyValsType.File, operationStr = "LINK" }, new List<int> { 1,2,3,4,5 } },
{ new MyKeyType { x = MyValsType.File, operationStr = "COPY" }, new List<int> { 10,20,30,40,50 } },
.....
}
List<int> GetValList( int i, string op)
{
// The following line causes error:
return ( m_Dict [ new MyKeyType { x = i, operationStr = op } ] );
}
你能告诉我为什么吗?非常感谢。如果您能够使用LINQ,您可以将GetValList更改为:
static List<int> GetValList(int i, string op)
{
return m_Dict.Where(x => x.Key.x == i && x.Key.operationStr.Equals(op)).Select(x => x.Value).FirstOrDefault();
}
当您使用一个类作为字典的键时,该类必须正确实现GetHashCode和Equals:dictionary调用这两个方法以了解该键与另一个键相同:如果两个实例x和y为GetHashCode和x返回相同的值。Equalsy==true;这两个键匹配 在MyKeyType类中不提供这两个重写将导致在运行时调用object.GetHashCode和object.Equals:仅当x和y是对同一实例的引用时,它们才会返回匹配,即object.ReferenceEqualsx,y==true
许多.Net framework类型(例如字符串、数字类型、日期时间等)正确地实现了这两种方法。对于您定义的类,您必须在代码中实现它们您将新对象传递给dictionary,所以它不存在。为什么?因为给定的键在字典中不存在。我猜您希望找到其属性x和operationStr与前一个条目的属性x和operationStr匹配的键,但这并不意味着该条目是相同的。例如:MyKeyType test=newmykeytype{x=1,operationStr=1};m_Dict.Addtest,新列表{1,2,3};如果您现在执行MyKeyType test0=newMyKeyType{x=1,operationStr=1};列表test2=m_Dict[test0];你会得到一个错误。顺便说一句,下次你应该试着做一点努力,问清楚,例如用一个像这样的简单例子。@MaximGoncharuk建议简单地重新定义给定变量很少是一个好建议。您不知道OP为什么需要这种数据结构。有多种选择来完成您的任务。您可以通过常规循环或LINQ查找与给定属性匹配的条目;或者,您可以重新定义类,以便立即支持某些比较,例如:。您没有重写Equals和GetHashCode,也没有为字典提供IEqualityComparer,因此MyKeyType类型的新对象永远不会与字典中存储的对象匹配。公开这样的字段的类对于字典键来说不是一个很好的候选,顺便说一句,更改字段并使字典条目丢失得不可挽回太容易了。是的,LINQ方法是最简单的方法。
static List<int> GetValList(int i, string op)
{
return m_Dict.Where(x => x.Key.x == i && x.Key.operationStr.Equals(op)).Select(x => x.Value).FirstOrDefault();
}