为什么我收到此 Resharper 警告 - 不会覆盖 'Object.Equals(object o) 和 'Object.GetHashcode()'

Why I am getting this Resharper warning - does not override 'Object.Equals(object o) and 'Object.GetHashcode()'

我有以下 class:

public class CalculateToValue
{
    public CalculateToValue(string normalValue)
    {
        NormalValue = normalValue;
    }

    public string NormalValue { get; private set; }

    public bool Equals(string other)
    {
        return NormalValue.Equals(other);
    }

    public bool Equals(CalculateToMax other)
    {
        return NormalValue.Equals(Enum.GetName(typeof(CalculateToMax),
    other));
    }

    public static bool operator ==(CalculateToValue a, CalculateToMax b)
    {
        if (((object) a == null) || ((object) b == null))
        {
            return false;
        }

        return a.Equals(b);
    }

    public static bool operator !=(CalculateToValue a, CalculateToMax b)
    {
        return !(a == b);
    }
  }

一切正常。但它在 class 上显示了 resharper 警告。它说 -

计算值定义运算符 == 或运算符 != 但不会覆盖 Object.Equals(object o)Object.GetHashcode()

如果我通过 resharper 生成代码,警告会得到修复。

   protected bool Equals(CalculateToValue other)
    {
        return string.Equals(NormalValue, other.NormalValue);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((CalculateToValue) obj);
    }

既然这个 class 是遗留的 class,我不确定上面的 resharper 生成的代码是否正常。

谁能解释一下为什么我会收到此警告?

根据 Microsoft 指南,当您重载运算符 "==" 时,您还应该覆盖 EqualsGetHashcode.

在此处查看指南: https://msdn.microsoft.com/en-us/library/7h9bszxx(v=vs.100).aspx

查看实施 Equals 的总体建议: https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx

Can someone please explain me why I get this warning?

考虑:

CalculateToValue ctv = whatever;
CalculateToMax ctm = whatever;
bool b1 = ctv.Equals(ctm);
bool b2 = ctv == ctm;
bool b3 = ctv.Equals((object)ctm);

您希望 b1 b2 和 b3 具有相同的值还是不同的值?

你用你的原始代码得到了什么结果?

您通过建议的修复获得了什么结果?

您现在是否认为您提出的解决方案是错误的? (你应该。)

当您查看这段代码时:您是否注意到 == 的实现有什么严重的错误?它说两个空值彼此不相等;那正确吗?我觉得不对。

Why does Resharper want you to override Equals?

您的 class 的消费者可能会认为 Equals== 在语义上是相同的,但 C# 语言并不强制执行这一点。

Is Resharper's proposed implementation acceptable?

如果您使用 Resharper 的代码,Equals== 在语义上将不相同,因为您现有的代码允许 CalculateToValue 的实例等于 [=16= 的实例],而 Resharper 的代码没有。

How should I fix this?

  1. 为应该发生的事情写一个规范。目标是让您真正知道您的代码打算做什么。例如,规范应该解释在什么情况下 CalculateToMax 的实例可能等于 CalculateToValue 的实例?
  2. 为规范的每一部分编写测试用例。 提供了一个很好的起点。
  3. 编写代码。

有关如何执行这些步骤的示例,我建议阅读 Eric Lippert 的 Integer division that rounds up 文章。

What else do I need to do?

考虑实施 IEquatable

Why else should I know.

您的 class 的消费者可能会假设 Equals/== 是自反的 (A==A),可交换的 (A==B ≡ B==A),和传递(A==B && B==C 意味着 A==C)。可能您的实现将是自反和传递的,而无需您进行太多计划,但是使您的实现具有可交换性实际上是不可能的,因为 CalculateToMax 是一个枚举。

通常,可以通过遵循一个简单的模板并将对基元上的相等操作的调用链接在一起来简化相等实现。 Resharper 很乐意自动生成此类代码。不幸的是,在您的情况下,您将 classes 与枚举进行比较......这真的很奇怪。

Is there a way to make this easier?

完全采用不同的方法。我建议不要使用相等运算符将枚举与 classes.

进行比较