Skip to content

False positive - C# IEquatable: Equals(object) not implemented alert when Equals(object?) is implemented #21128

@Thomasedv

Description

@Thomasedv

Description of the false positive

CodeQL will complain about a missing override for Equals(object obj) not existing, if the Equals method is implemented within a nullable object as parameter. Using Equals(object? obj) is valid.

Two different alerts appeared on a PR.

Code sample

Sadly, working in closed source, but this sample should do. I do not know if this triggers the false positive in practice, as I can't push it to test, but it should give you a good example. I also added a small a bit of code to show that Equals(object? obj) is valid and working when using Equals().

using System;
using System.Linq;

#nullable enable
public class Program
{
	public class MyClass : IEquatable<MyClass>
	{
		private object property;
		public MyClass()
		{
			property = 1;
		}

		public bool Equals(MyClass? other)
		{
			Console.WriteLine("MyClass? called");
			if (ReferenceEquals(null, other))
			{
				return true;
			}

			return Equals(property, other.property);
		}

		public override bool Equals(object? obj)
		{
			Console.WriteLine("object? called");
			if (ReferenceEquals(null, obj))
			{
				return false;
			}

			if (ReferenceEquals(this, obj))
			{
				return true;
			}

			if (obj.GetType() != GetType())
			{
				return false;
			}

			return Equals((MyClass)obj);
		}

		public override int GetHashCode()
		{
			return HashCode.Combine(property);
		}
	}

	public static void Main()
	{
		var a = new MyClass();
		var b = new MyClass();
		Console.WriteLine(a.Equals(b)); // Equals(MyClass? other)
		Console.WriteLine(Equals(a, b)); // Equals(object? obj)
		Console.WriteLine(IEquatable<MyClass>.Equals(a, b)); // Equals(object? obj)
	}
}

Check 1 (failure check)

The CodeQl error message goes as follows for the override bool Equals(object? obj) line:
Class 'MyClass' does not implement Equals(object), but it implements IEquatable.Equals
The IEquatable.Equals points to bool Equals(MyClass? other).

Error 2 (alert):
The warning goes for the same function override bool Equals(object? obj)
The declaring(MyClass) type of this 'Equals(Object)' method does not override 'Equals(object)'.

Source for alerts
https://github.com/github/codeql/blob/main/csharp/ql/src/API%20Abuse/ClassDoesNotImplementEquals.ql

https://github.com/github/codeql/blob/28b6aa8616a393ebb45186e3ba4df004a0f3ef4e/csharp/ql/src/API%20Abuse/IncorrectEqualsSignature.ql

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions