我在 .NET Framework 中的 GUID 类型源代码中看到,Equals 方法和 ==
运算符的实现非常相似。
为什么 ==
运算符不调用第一个参数的 Equals 方法呢?就像这样:
public static bool operator ==(Guid a, Guid b)
{
return a.Equals(b);
}
我在 .NET Framework 中的 GUID 类型源代码中看到,Equals 方法和 ==
运算符的实现非常相似。
为什么 ==
运算符不调用第一个参数的 Equals 方法呢?就像这样:
public static bool operator ==(Guid a, Guid b)
{
return a.Equals(b);
}
public static bool operator ==(Guid a, Guid b) { // Now compare each of the elements
这本身没有意义。在文件中寻找其他地方的评论:
public bool Equals(Guid g) { // Now compare each of the elements
但同时也
// Returns true if and only if the guid represented
// by o is the same as this instance.
public override bool Equals(Object o)
{
Guid g;
// Check that o is a Guid first
if(o == null || !(o is Guid))
return false;
else g = (Guid) o;
// Now compare each of the elements
该评论只在最后一个方法中才有意义。这非常强烈地表明了Guid.Equals(Object)
的实现是最先完成的。Guid.operator ==
和Guid.Equals(Guid)
是基于Guid.Equals(Object)
实现的,那么这将是不好的,或者至少是次优的,因为那个最后的方法需要无意义的分配,虽然在常见情况下几乎不会注意到,但肯定有一些代码中发生了Guid
比较,在紧密循环中分配将是可测量的。operator ==
使用Equals(Guid)
,反之亦然,但复制并粘贴两次而不是一次确实没有任何额外的工作。o==null
是多余的:如果o==null
,那么!(o is Guid)
必定为真。 - user743382
IEquatable
之前就存在了。当加入IEquatable
后,他们选择复制操作符代码而不是重写它(可能是避免更改旧代码的政策?)虽然这只是纯属推测。也可能是为了更积极的内联使用极小的优化考虑,但这对于代码重复来说并不是一个特别值得的原因。或者这只是一个错误,没有人在代码审查中认为它足够糟糕,值得花费精力去修复。 - Dan BryantGuid
的情况下,它是一个值类型,因此它不能为null。重新打开这个问题... - HabibGuid
的情况,由于实现相同,它可以调用Equals
,但这样会进一步进入堆栈,并增加不必要的开销。同样,如果由于某种原因Equals
的实现与==
不同,每个基础实现已经分离,无需进行重构。此外,正如 @Habib 所说,由于上下文不同,这并不一定是被标记为重复的同一个问题,我建议在标题中添加for Guid
。 - Der Kommissar