7

I've seen in the souce code of the GUID type in the .NET Framework that the implementation of Equals and the == operator execute very similar code.

Why doesn't the == operator call the Equals method on the firts argument? Something like this:

public static bool operator ==(Guid a, Guid b)
{ 
    return a.Equals(b);  
}
Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
Tao Gómez Gil
  • 2,228
  • 20
  • 36
  • 3
    Voting to close as opinion-based, we can't read the framework designers/developers minds. – BradleyDotNET Jun 12 '15 at 16:06
  • I think its because of primitive vs Object issues – nafas Jun 12 '15 at 16:07
  • 1
    My guess would be that the operator implementation existed prior to the addition of `IEquatable` to the framework. When that was added, they chose to duplicate the operator code rather than rewrite it (perhaps a policy of avoiding changing old code?) This is pure speculation, though. Could also be an extremely minor optimization consideration for more aggressive inlining, but wouldn't strike me as a particularly worthwhile reason for code repetition in this case. Or it was just a mistake and nobody in code review thought it was bad enough to be worth the effort to fix. – Dan Bryant Jun 12 '15 at 16:10
  • 1
    I don't think the linked duplicate question actually answers this question, in case of `Guid` it is a value type, thus it can't be null. Re opening the question.. – Habib Jun 12 '15 at 16:11
  • 1
    For the case of `Guid`, as the implementations are the same it **could** call `Equals`, however, in doing so it would proceed further into the stack, and add unnecessary overhead. Likewise, if for whatever reason the implementation of `Equals` ever *needs* to be different than `==`, the base implementation of each is already separated, and no refactoring needs done. Also, as @Habib said, this isn't necessarily the same question as was marked duplicate due to context, I would suggest adding `for Guid` to the title. – Der Kommissar Jun 12 '15 at 16:12
  • 1
    @BradleyDotNET there are plenty other questions on implementation details of the .NET Framework, and sometimes they receive really good answers by people who know a lot or even MS employees. You shouldn't close this just because *you* cannot answer. – user247702 Jun 12 '15 at 16:18
  • 1
    @Stijn I agree you (or I) shouldn't close because we do not know the answer. However, "Why does the framework do X" or "Why is this framework implemented in Y way" are inherently opinion-based, as there are innumerable reasons why the design team *could* have made one decision or another. They are unanswerable since no one outside of such a team can provide a reasonably definitive answer. – BradleyDotNET Jun 12 '15 at 16:22
  • Adding to Bradley's comments - what difference does it make? Sure it's interesting but unless there's a meaningful technical reason it just comes down to coding style. – D Stanley Jun 12 '15 at 16:28
  • 1
    If you are wondering if *you* should use your proposed implementation, please ask that (as it can be answered objectively) and use the Guid code as an example if you feel it is relevant. – BradleyDotNET Jun 12 '15 at 16:40

1 Answers1

6

The comment is very telling:

public static bool operator ==(Guid a, Guid b)
{
    // Now compare each of the elements

This doesn't make sense by itself. Looking for that comment elsewhere in the file:

public bool Equals(Guid g)
{
    // Now compare each of the elements

but also

// 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

The comment only makes sense in that last method. This is a very strong indication that the Guid.Equals(Object) implementation came first.

It would be bad, or at least sub-optimal, if Guid.operator == and Guid.Equals(Guid) were implemented on top of Guid.Equals(Object), as that last method requires pointless allocations, and while it will hardly be noticeable in the common cases, there are certainly Guid comparisons that happen in some code in tight loops where the allocations would be measurable.

Now, it would certainly have been possible to make operator == use Equals(Guid), or vice versa, but it really isn't any additional work to copy and paste it twice instead of once.

  • 1
    By the rather dull comments, like "first check this is a GUID", it seems that this perhaps was implemented by a rather new developer, who might not be familiar with the DRY principal :) – Yuval Itzchakov Jun 12 '15 at 17:00
  • 3
    @YuvalItzchakov Also that the `o == null` is redundant: if `o == null`, then `!(o is Guid)` is necessarily true. –  Jun 12 '15 at 22:35