【问题标题】:Determining if two objects are equal判断两个对象是否相等
【发布时间】:2013-04-29 17:12:05
【问题描述】:

我正在尝试测试一个对象是否等于给定条件(名称相等)的对象列表中的一个,如果是,则不要将其添加到列表中,否则添加它。我必须使用具有此签名“static int Find(List c, Coffee x)”的方法。 Find 在 c 中查找 x 并返回有效索引(即 0、1、...),如果 x 存在于 c 中,否则返回 -1。当我传递完全匹配时,我的 equals 方法似乎没有意识到名称是相同的。为什么是这样?这是我的代码:

        Coffee obv = new Coffee();
        Decaf decafCoffee = null;
        Regular regularCoffee = null;
        List<Coffee> inventory = new List<Coffee>();

        if (some sxpression)
            {
                decafCoffee = new Decaf(name, D, C, M);
                find = obv.Find(inventory, decafCoffee);
                if (find == -1)
                {
                    inventory.Add(decafCoffee);
                }
            }


          public class Coffee : IDisposable
          {
              public override bool Equals(object obj)
              {
                  if (obj is Coffee)
                  {
                    bool isNameEqual = Name.Equals(this.Name);

                 return (isNameEqual);
                  }
        return false;
    }

        public int Find(List<Coffee> c, Coffee x)
    {
        if (c.Equals(x))
        {
            return 0;
        }

        return -1;
    }
        }          

【问题讨论】:

  • List 永远不会等于 Coffee 对象。
  • List&lt;Coffee&gt;永远怎么能等于Coffee?也许是时候重新审视您的Find 方法了?在不提供适用于相同字段的 GetHashCode 方法的情况下重新定义相等性也是一个非常糟糕的主意。
  • "Find seeks x in c .." 嗯,不是的。它只是检查是否c.Equals(x)。因为 "x" 是 Coffee 类型,而 "c" 是 List&lt;Coffee&gt; 类型,它们不会相等。

标签: c# list find equals


【解决方案1】:

您正在测试 List 与 Coffee 实例的相等性。这将始终返回 -1。你想要的是 c.Contains(x)。请记住,当您覆盖 Equals 时,您还应该为 GetHashCode() 提供类似的覆盖。在此处查找对象上的Microsoft advice on implementing and overriding Equals

public int Find(List<Coffee> c, Coffee x) {
    return c.IndexOf(x);
}

public override int GetHashCode()
{
    return Name == null ? 0 : Name.GetHashCode();
}

【讨论】:

    【解决方案2】:

    你的错误在这里:

    public int Find(List<Coffee> c, Coffee x)
    {
        if (c.Equals(x))  // <-- this will never return true
        {
            return 0;
        }
    
        return -1;
    }
    

    但是,您的Find 方法是不必要的。使用List&lt;T&gt;.IndexOf 保持您的概念:

    var index = inventory.IndexOf(decafCoffee);
    

    【讨论】:

      【解决方案3】:

      你的问题在这里:

      public int Find(List<Coffee> c, Coffee x)
      {
          if (c.Equals(x))
          {
              return 0;
          }
      
          return -1;
      }
      

      cList&lt;Coffee&gt; 不是 Coffee 对象。

      您需要更改您的代码,以便它遍历列表以查看它是否包含x

      for (int i = 0; i < c.Count; ++i)
          if (c[i].Equals(x))
              return i;
      
      return -1
      

      【讨论】:

        【解决方案4】:

        你可以做如下,因为你有Equals方法,你可以用它来寻找匹配的项目

        public int Find(List<Coffee> c, Coffee x)
        {
            if (c.Any(i=>i.Equals(x))
            {
                return 0;
            }
        
            return -1;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多