C# 字典上说钥匙没有';当它存在时,它就不存在了
我有一个字典,其中键是C# 字典上说钥匙没有';当它存在时,它就不存在了,c#,autodesk,C#,Autodesk,我有一个字典,其中键是XYZ对象,值是boolean。XYZ类来自Autodesks API,因此它不是我创建的类。我正在尝试检查字典中是否存在密钥 我的问题是:如果字典包含键new XYZ(1,1,1),我将使用myDictionary检查字典是否包含此键。ContainsKey(new XYZ(1,1,1)始终返回false 为什么会发生这种情况?我想类XYZ需要实现它的Equals方法,但正如我前面提到的,我没有创建这个类,它是Autodesks API的一部分。或者我做错了什么 Dict
XYZ
对象,值是boolean
。XYZ类来自Autodesks API,因此它不是我创建的类。我正在尝试检查字典中是否存在密钥
我的问题是:如果字典包含键new XYZ(1,1,1)
,我将使用myDictionary检查字典是否包含此键。ContainsKey(new XYZ(1,1,1)
始终返回false
为什么会发生这种情况?我想类XYZ
需要实现它的Equals
方法,但正如我前面提到的,我没有创建这个类,它是Autodesks API的一部分。或者我做错了什么
Dictionary<XYZ, bool> prevPnts = new Dictionary<XYZ, bool>();
prevPnts[new XYZ(1,1,1)] = true;
// Always says the pnt doesnt exist?
if (prevPnts.ContainsKey(new XYZ(1,1,1)))
TaskDialog.Show("Contains");
else TaskDialog.Show("NOT Contains");
Dictionary prevPnts=new Dictionary();
prevPnts[new XYZ(1,1,1)]=真;
//总是说pnt不存在?
if(prevPnts.ContainsKey(新的XYZ(1,1,1)))
TaskDialog.Show(“包含”);
else TaskDialog.Show(“不包含”);
使用Konrads答案的解决方案
class XYZEqualityComparer : IEqualityComparer<XYZ>
{
public bool Equals(XYZ a, XYZ b)
{
if (Math.Abs(a.DistanceTo(b)) <= 0.05)
return true;
return false;
}
public int GetHashCode(XYZ x)
{
int hash = 17;
hash = hash * 23 + x.X.GetHashCode();
hash = hash * 23 + x.Y.GetHashCode();
hash = hash * 23 + x.Z.GetHashCode();
return hash;
}
}
Dictionary<XYZ, bool> prevPnts = new Dictionary<XYZ, bool>(new XYZEqualityComparer());
XYZEqualityComparer类:IEqualityComparer
{
公共布尔等于(XYZ a,XYZ b)
{
if(数学绝对值(a.距离到(b))对于不重写Equals
和GetHashCode
方法的类,比较算法将默认为引用相等而不是值相等。因此,尽管类实例的值字段/属性的值可能相同,但实例本身不同,因此相等失败
在这种情况下,除非为该类定义了IEqualityComparer
实现,否则基本上不能将该类本身用作字典中的键。请查看向字典提供自己的IEqualityComparer
,因为它不知道如何比较XYZ
类(严格地说,它通过参考来比较它们):
XYZEqualityComparer类:IEqualityComparer
{
公共布尔等于(XYZ a,XYZ b)
{
返回a.X==b.X&&a.Y==b.Y&&a.Z==b.Z;
}
公共整数GetHashCode(XYZ x)
{
int hash=x.x^x.Y^x.Z;
返回hash.GetHashCode();
}
}
然后:
Dictionary<XYZ, bool> prevPnts = new Dictionary<XYZ, bool>(new XYZEqualityComparer());
Dictionary prevPnts=newdictionary(new XYZEqualityComparer());
注意:我对GetHashCode
的实现只是示例性的。请阅读以获得更好的替代方案。正如您正确观察到的,如果XYZ类没有实现等于和GetHashCode
方法,那么它将进行参考比较(仅当它们引用堆上的同一对象时为true)
由于您没有访问该类的权限,解决方法之一是将其包装到您自己的类中,您可以在其中编写一个Equals方法,该方法使用XYZ的内容进行适当的比较
class WrapperXYZ
{
XYZ xyz;
public override bool Equals(object other)
{
if(other is typeof(XYZ))
{
// check the contents
}
else
{
return false;
}
}
// TODO: write a hash method if you are using a dictionary
}
是的,我在回答中指出了这一点。是的,我知道。谢谢你的提示。与其包装类型只是为了覆盖Equals
和GetHashCode
,你只需编写一个IEqualityComparer
,它是为了定义其他类型的相等性而设计的。
class WrapperXYZ
{
XYZ xyz;
public override bool Equals(object other)
{
if(other is typeof(XYZ))
{
// check the contents
}
else
{
return false;
}
}
// TODO: write a hash method if you are using a dictionary
}