CodeQL 文档

类未实现 Equals(object)

ID: cs/class-missing-equals
Kind: problem
Security severity: 
Severity: error
Precision: medium
Tags:
   - reliability
   - maintainability
Query suites:
   - csharp-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

当调用 Equals(object) 的对象的类未定义其自己的 Equals(object) 方法时,将改为调用在其基类之一中定义的 Equals(object) 方法。在最坏的情况下,将调用 System.ObjectEquals(object) 方法,从而导致引用相等性检查。这可能不是预期的结果。

实现 == 运算符的类还应重写 Equals(object) 方法,因为否则这两种相等性形式的行为将有所不同,从而导致意外行为。

建议

为突出显示的类实现 Equals(object) 方法。检查突出显示的类的子类,以确定它们是否也应实现自己的 equals 方法。

示例

此示例的输出表明“car1 等于 car2”,尽管事实上一个是含铅版本,一个是无铅版本。这是因为 GasolineCar 类正在从 Car 继承 Equals(object),并且该方法指出如果两辆 Car 的品牌和型号相同,则它们相等。

using System;

class Bad
{
    class Car
    {
        protected string make;
        protected string model;

        public Car(string make, string model)
        {
            this.make = make;
            this.model = model;
        }

        public override bool Equals(object obj)
        {
            if (obj is Car c && c.GetType() == typeof(Car))
                return make == c.make && model == c.model;
            return false;
        }
    }

    class GasolineCar : Car
    {
        protected bool unleaded;

        public GasolineCar(string make, string model, bool unleaded) : base(make, model)
        {
            this.unleaded = unleaded;
        }
    }

    public static void Main(string[] args)
    {
        var car1 = new GasolineCar("Ford", "Focus", true);
        var car2 = new GasolineCar("Ford", "Focus", false);
        Console.WriteLine("car1 " + (car1.Equals(car2) ? "does" : "does not") + " equal car2.");
    }
}

在修改后的示例中,GasolineCar 重写了 Equals(object),并且输出为“car1 不等于 car2”,符合预期。

using System;

class Good
{
    class Car
    {
        protected string make;
        protected string model;

        public Car(string make, string model)
        {
            this.make = make;
            this.model = model;
        }

        public override bool Equals(object obj)
        {
            if (obj is Car c && c.GetType() == typeof(Car))
                return make == c.make && model == c.model;
            return false;
        }
    }

    class GasolineCar : Car
    {
        protected bool unleaded;

        public GasolineCar(string make, string model, bool unleaded) : base(make, model)
        {
            this.unleaded = unleaded;
        }

        public override bool Equals(object obj)
        {
            if (obj is GasolineCar gc && gc.GetType() == typeof(GasolineCar))
                return make == gc.make && model == gc.model && unleaded == gc.unleaded;
            return false;
        }
    }

    public static void Main(string[] args)
    {
        var car1 = new GasolineCar("Ford", "Focus", true);
        var car2 = new GasolineCar("Ford", "Focus", false);
        Console.WriteLine("car1 " + (car1.Equals(car2) ? "does" : "does not") + " equal car2.");
    }
}

参考

  • ©GitHub 公司
  • 条款
  • 隐私