Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 字典上说钥匙没有';当它存在时,它就不存在了_C#_Autodesk - Fatal编程技术网

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
}