Переопределение Equals с использованием другого Equals

Рейтинг: 1Ответов: 1Опубликовано: 02.03.2025
public class User
{
    public string Name {get; set; }

    public override bool Equals(object obj)
        {
            if(obj == null) return false;

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

            User p = (User)obj;

            return Name.Equals(p.Name); // 1

            return Name == p.Name;  // 2
        }
}

как правильнее переопределять метод Equals?

вариант 1 - вызов Equals строки в Name

вариант 2 - сравнение через ==

или это эквивалентные способы?

Ответы

▲ 3Принят

Сравнивать строки здесь на мой взгляд лучше с использованием строкового string.Equals, к тому же там можно параметр задать: с учётом регистра, без учёта и т.д.

Я бы как-то так написал.

public class User : IEquatable<User>
{
    public string Name { get; set; }

    public bool Equals(User other)
    {
        return other is not null && string.Equals(Name, other.Name, StringComparison.Ordinal);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as User);
    }

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

Если моего мнения недостаточно, то вот пример из недр .NET, класс HttpMethod:

public partial class HttpMethod : IEquatable<HttpMethod>
{
    private readonly string _method;

    // ...

    private int _hashcode;

    // ...

    public bool Equals([NotNullWhen(true)] HttpMethod? other)
    {
        if (other is null)
        {
            return false;
        }

        if (object.ReferenceEquals(_method, other._method))
        {
            // Strings are static, so there is a good chance that two equal methods use the same reference
            // (unless they differ in case).
            return true;
        }

        return string.Equals(_method, other._method, StringComparison.OrdinalIgnoreCase);
    }

    public override bool Equals([NotNullWhen(true)] object? obj)
    {
        return Equals(obj as HttpMethod);
    }

    public override int GetHashCode()
    {
        if (_hashcode == 0)
        {
            _hashcode = StringComparer.OrdinalIgnoreCase.GetHashCode(_method);
        }

        return _hashcode;
    }

    // ...
}