为什么 == 实现不调用 Guid 的 Equals 方法?

7

我在 .NET Framework 中的 GUID 类型源代码中看到,Equals 方法和 == 运算符的实现非常相似。

为什么 == 运算符不调用第一个参数的 Equals 方法呢?就像这样:

public static bool operator ==(Guid a, Guid b)
{ 
    return a.Equals(b);  
}

3
投票关闭,因为这是基于个人观点的,我们无法读取框架设计师/开发者的想法。 - BradleyDotNET
1
我的猜测是:操作符实现在框架添加IEquatable之前就存在了。当加入IEquatable后,他们选择复制操作符代码而不是重写它(可能是避免更改旧代码的政策?)虽然这只是纯属推测。也可能是为了更积极的内联使用极小的优化考虑,但这对于代码重复来说并不是一个特别值得的原因。或者这只是一个错误,没有人在代码审查中认为它足够糟糕,值得花费精力去修复。 - Dan Bryant
1
我认为链接的重复问题实际上并没有回答这个问题,在Guid的情况下,它是一个值类型,因此它不能为null。重新打开这个问题... - Habib
1
对于 Guid 的情况,由于实现相同,它可以调用 Equals,但这样会进一步进入堆栈,并增加不必要的开销。同样,如果由于某种原因 Equals 的实现与 == 不同,每个基础实现已经分离,无需进行重构。此外,正如 @Habib 所说,由于上下文不同,这并不一定是被标记为重复的同一个问题,我建议在标题中添加 for Guid - Der Kommissar
1
@BradleyDotNET,关于.NET Framework实现细节的问题还有很多,有时候会得到非常好的答案,这些答案来自那些非常了解或者甚至是微软员工。你不应该因为无法回答而关闭它。 - user247702
显示剩余4条评论
1个回答

6
评论非常有意义:
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),反之亦然,但复制并粘贴两次而不是一次确实没有任何额外的工作。

1
从那些相当乏味的注释中,比如“首先检查这是否为GUID”,似乎这可能是由一位相对较新的开发人员实现的,他可能不熟悉DRY原则 :) - Yuval Itzchakov
3
同时,o==null是多余的:如果o==null,那么!(o is Guid)必定为真。 - user743382

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接