为什么我得到这个Resharper警告-不覆盖'对象.= (object 0)和'object . ge
本文关键字:object ge 对象 覆盖 Resharper 警告 为什么 | 更新日期: 2023-09-27 18:02:55
我有以下类:
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);
}
现在,因为这个类是一个遗留类,我不确定上面resharper生成的代码是否正确。
谁能告诉我为什么我得到这个警告?谁能告诉我为什么我得到这个警告?
考虑:
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的代码不允许。
我该如何解决这个问题?
- 为应该发生的事情写一个规范。我们的目标是让您真正了解代码要做什么。例如,规范应该解释在什么情况下
CalculateToMax
的实例可能等于CalculateToValue
的实例? - 为规格说明的每个部分编写测试用例。Eric的回答提供了一个很好的起点。 写你的代码。
关于如何遵循这些步骤的示例,我建议阅读Eric Lippert的整型除法,它是本文的总结。
我还需要做什么?
考虑实现等价。
不然我为什么要知道。
你的类的消费者可能会假设Equals
/==
是自反的(A==A),交换的(A==B≡B==A),传递的(A==B &&B==C意味着A==C)。也许你的实现是自反的和可传递的,而不需要你做太多的计划,但是让你的实现可交换是不可能的,因为CalculateToMax
是一个enum。
有办法使这更容易吗?
采用完全不同的方法。我不建议使用相等运算符来比较枚举和类。
根据Microsoft指南,当您重载"=="
操作符时,您也应该重载Equals
和GetHashcode
。
在这里查看指南: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