Meh*_*dad 20 c# warnings equals equals-operator
对于下面的代码
public struct Person
{
public int ID;
public static bool operator ==(Person a, Person b) { return a.Equals(b); }
public static bool operator !=(Person a, Person b) { return !a.Equals(b); }
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器会给我这些警告?
没有定义下面的方法有什么问题?
warning CS0660: 'Person' defines operator == or operator != but
does not override Object.Equals(object o)
warning CS0661: 'Person' defines operator == or operator != but
does not override Object.GetHashCode()
Run Code Online (Sandbox Code Playgroud)
Mat*_*hen 19
编辑:此答案已得到纠正,除其他事项外,请注意用户定义的值类型不会生成==,并提及性能问题ValueType.Equals.
一般来说,覆盖一个,但不是全部,是令人困惑的.用户希望既不会被覆盖,也不会被覆盖,具有相同的语义.
微软对此州的建议(以及其他事项):
实现Equals方法时实现GetHashCode方法.这使Equals和GetHashCode保持同步.
每当实现相等运算符(==)时重写Equals方法,并使它们执行相同的操作.
在您的情况下,您有正当理由推迟Equals(编译器不会自动实现==)并仅覆盖这两个(==/ !=).但是,由于ValueType.Equals使用反射,仍然存在性能问题:
"覆盖特定类型的Equals方法以提高方法的性能,并更接近地表示类型的相等概念."
因此,仍然建议最后覆盖所有(==/ !=/ Equals).当然,对于这个简单的结构,性能可能无关紧要.
框架内普遍期望某些操作应始终产生相同的结果。原因是某些操作(特别是排序和搜索,构成任何应用程序的很大一部分)都依赖于这些不同的操作来产生有意义且一致的结果。在这种情况下,您将打破以下两个假设:
==之间存在有效的运算,则应产生与相同的结果aba.Equals(b)!=之间存在有效的运算,则应产生与相同的结果ab!a.Equals(b)a和b存在,其中a == b,然后a和b应该产生相同的密钥存储在哈希表时。前两个,IMO,是显而易见的。如果要定义两个对象相等意味着什么,则应包括检查两个对象相等的所有方法。请注意,编译器不会(通常不能)强制您实际上遵循这些规则。不会对操作员的身体进行复杂的代码分析以查看他们是否已经模仿,Equals因为在最坏的情况下,这等效于解决暂停问题。
但是,它可以做的是检查最有可能违反这些规则的情况,特别是您提供了自定义比较运算符,而没有提供自定义Equals方法。这里的假设是,如果您不希望操作员执行某些特殊操作,则无需费心提供操作员,在这种情况下,您应该为需要同步的所有方法提供了自定义行为。
如果您确实实现Equals了==与编译器不同的东西,则不会抱怨。您将达到C#愿意阻止您做一些愚蠢的事情的极限。它愿意阻止您不小心在代码中引入细微的错误,但是如果您要这样做的话,它可以让您有目的地这样做。
第三个假设与以下事实有关:框架中的许多内部操作都使用哈希表的某些变体。如果我有两个对象,按照我的定义,它们是“相等”,那么我应该能够做到这一点:
if (a == b)
{
var tbl = new HashTable();
tbl.Add(a, "Test");
var s = tbl[b];
Debug.Assert(s.Equals("Test"));
}
Run Code Online (Sandbox Code Playgroud)
这是哈希表的基本属性,如果突然不正确,将导致非常奇怪的问题。
| 归档时间: |
|
| 查看次数: |
15862 次 |
| 最近记录: |