繁体   English   中英

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

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

我有以下课程:

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);
    }
  }

一切正常。 但这显示了对类的警告。 它说 -

计算值定义运算符==或运算符!=但不覆盖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);
    }

现在,由于该类是旧类,所以我不确定上面的reshaper生成的代码是否还可以。

有人可以解释一下我为什么收到此警告吗?

有人可以解释一下我为什么收到此警告吗?

考虑:

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

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

您的原始代码会得到什么结果?

您提出的修复程序会得到什么结果?

您现在是否认为您建议的修复程序是错误的? (你应该。)

在查看此代码时:您是否注意到==的实现存在任何严重错误? 它说两个空值彼此不相等; 那正确吗? 对我来说似乎不对。

为什么Resharper希望您覆盖Equals

您的类的使用者可能会认为Equals==在语义上是相同的,但是C#语言不会强制这样做。

Resharper的拟议实施是否可以接受?

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

我该如何解决?

  1. 编写确切说明应该发生的情况的规范。 目的是让您真正知道您的代码打算做什么。 例如,规范应解释在什么情况下CalculateToMax的实例可以等于CalculateToValue的实例?
  2. 为您的每个规范编写测试用例。 埃里克(Eric)的回答提供了一个很好的起点。
  3. 编写您的代码。

有关如何执行这些步骤的示例,我建议阅读Eric Lippert的Integer部门,该部门对本文进行汇总

我还需要做什么?

考虑加强IEquatable

我为什么还要知道。

此类的消费者可能会认为Equals / ==是反身(A == A),可交换(A == B≡B == A)和可传递(A == B && B == C意味着A == C)。 无需过多计划,您的实现可能是自反的和可传递的,但是由于CalculateToMax是枚举,因此使实现实现可交换性实际上是不可能的。

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

有没有办法使这更容易?

完全采用另一种方法。 我建议不要使用相等运算符将枚举与类进行比较。

根据Microsoft的准则,当重载运算符"==" ,还应该重写EqualsGetHashcode

在此处检查准则: https : //msdn.microsoft.com/zh-cn/library/7h9bszxx(v=vs.100).aspx

检查有关实施Equals总体建议: https : Equals ( v= Equals

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM