【问题标题】:How can I overload the "==" operator to determine of two ID numbers are the same?如何重载“==”运算符来确定两个 ID 号是否相同?
【发布时间】:2019-03-12 19:32:59
【问题描述】:

我需要编写一个方法,将两个员工对象作为输入参数并比较它们的 ID 以确定它们是否匹配。

目前还不完整;但到目前为止,我有一个 Employee 类,它从“Person”类继承名字和姓氏属性,并将 ID 作为自己的属性。我正在员工文件中编写该方法,并且已经在我的程序中实例化了 2 个示例员工。至于重载 ==,我遇到了一个错误,上面写着“Employee”定义了 operator == 但没有覆盖 Object.Equals。”它还说我需要定义“!=”,但我很困惑如何设置 != 重载,当它甚至不包含在此方法中时。

我见过两种比较方法,一种返回真或假,另一种只是将“匹配”写入控制台。其中任何一个都可以满足我的目的,但我无法找到解决这些错误的方法,或者在这种情况下如何更改代码以确定 2 个员工 ID 之间的匹配。下面是我的代码;对于可能出现的问题,我将不胜感激! (我有一种感觉,它可能很不对劲)。我也不确定如何调用该方法,但我目前正在尝试弄清楚。

程序文件:

namespace OperatorOverload
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee example = new Employee();

            example.FirstName = "Kitty";
            example.LastName = "Katz";
            example.ID = 24923;

            Employee example2 = new Employee();
            example2.FirstName = "John";
            example2.LastName = "Dudinsky";
            example2.ID = 39292;

            Console.ReadLine();
        }
    }
}

员工等级:

namespace OperatorOverload
{
    class Employee : Person
    {
        public int ID { get; set; }

        public static bool operator==(Employee employee, Employee employee2)
        {
            if (employee.ID == employee2.ID)

                return true;        
            else           
                return false;
            }
        }
    }

人员类别:

namespace OperatorOverload

{
    public class Person
    {
       public string FirstName { get; set; }
        public string LastName { get; set; }      
    }
}

【问题讨论】:

  • 您可能会找到您的解决方案herehere
  • 是的,这与我的情况非常相似。谢谢 Veverke!
  • 引用“当一个类型重载相等运算符时,它还必须重写 Equals(Object) 方法以提供相同的功能。这通常通过编写 Equals(Object) 方法来实现重载的相等运算符,如下例所示。"

标签: c# overloading


【解决方案1】:

这是覆盖Equals 方法的更好方法:

public override bool Equals(object obj)
{
    if (obj is null) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj.GetType() != this.GetType()) return false; //optional. depends on logic
    return this.ID.Equals(((Employee)obj).ID);
}

【讨论】:

  • 谢谢斯莫尔查诺夫斯基!我会记下来的。
【解决方案2】:

你应该使用这个类。覆盖 operator!=, operator==Equals(object) 方法。

class Employee : Person
    {
        public int ID { get; set; }

        public static bool operator ==(Employee employee, Employee employee2)
        {
            if (employee.ID == employee2.ID)
                return true;
            else
                return false;

            //but you should use 
            //return employee.ID == employee2.ID;
        }

        public static bool operator !=(Employee employee, Employee employee2)
        {
            return employee.ID != employee2.ID;
        }

        public override bool Equals(object obj)
        {
            var emp = obj as Employee;
            if (emp == null)
                return false;

            return this.ID.Equals(emp.ID);
        }
    }

【讨论】:

    【解决方案3】:

    您还需要覆盖Equals 方法:

    public override bool Equals(Object Obj)
    {
        Person person = obj as Person;
    
        if(person == null)
            return false;
    
        return this.ID.Equals(person.ID);
    }
    

    微软的recommandations

    在实现 Equals 时实现 GetHashCode 方法 方法。这使 Equals 和 GetHashCode 保持同步。

    在实现相等时重写 Equals 方法 运算符 (==),并让它们做同样的事情。

    【讨论】:

      【解决方案4】:

      编译器基本上是在告诉你,如果你想重载 Employee 类的 == 运算符,你还必须重写 Object.Equals 方法和 != 运算符,这样你才能获得可以使用的一致语义比较 Employee 类型的实例。

      这意味着您不必寻找解决方法:您只需重载 != 运算符并覆盖 Object.Equals 以便通过 ID 而不是通过引用比较 Employee 对象(如果您不这样做,默认情况下会这样做)提供您自己的相等语义)。

      【讨论】:

      • @FreddieMercury 记得同时覆盖 Object.GetHashCode(这是每次覆盖 Object.Equals 时的最佳实践,这样您就可以将您的类用作字典中的键)。这样做的基本规则是如果两个对象相等,那么它们必须具有相同的哈希码。在您的场景中,这意味着 Employee 对象的哈希码计算为 ID.GetHashCode()
      【解决方案5】:

      您需要做的是使用 Equals 函数并像这样覆盖它:

      public override bool Equals(object obj)
      {
          var item = obj as Employee;
      
          if (item == null)
          {
              return false;
          }
      
          return this.ID.Equals(item.ID);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多