Equals(Object,Guid.Empty)和Object == Guid.Empty是否相同?

3
以下代码行的结果是什么:

以下是代码:

if (Equals(comp.Id, Guid.Empty)) return;

总是与下一行代码相同吗?

if(comp.Id == Guid.Empty) return;

源代码是你的好朋友。 - Jeroen Vannevel
1
你的代码没有给出“Equals”的定义,或者“==”是一个重载运算符,因此我们无法告诉你。 - Dai
3个回答

4
  1. 默认实现都是在引用类型中检查引用和在值类型中检查实际内容。
  2. 不一定,== 和 .Equals 都可以被重载。
  3. Guid 和字符串都覆盖了 == 和 .Equals,实现方式相同,检查两个 Guid 之间的相等性是基于值的,比较两个字符串的值也是基于值的。然而,无论如何比较字符串和 Guid,结果都将始终返回 false。你需要将 Guid.ToString() 的结果与字符串值进行比较,或者将字符串转换为 Guid。

摘自http://social.msdn.microsoft.com/Forums/en-US/a505b091-9166-4c74-91dd-a8e9eb6ad001/-and-equals-comparision-for-systemguid-and-string?forum=csharplanguage

我认为你不应该假定,如果你的 Equals 方法看起来像这样

Equals(guid id1, guid id2)
{
   return id1 == id2 ;
}

希望这样说起来有意义...等于需要上下文。
如果equals是这样的...
equsl(guid id1, guid id2)
{
   string firstG = id1.toString();
   string secondG = id2.toString();
   return firstG == secondG;
}

在这里,你可以看到这将是一个字符串比较而不是GUID比较……结果可能会不同……

你为什么认为在这里string相关呢? - svick
@svick 在问题中的 Equals 没有类或命名空间名称,因此我们不知道它是由用户定义的。我认为他只是指出,如果它是用户定义的,那么如果没有看到实现,我们的答案就不会很有帮助。 - IllusiveBrian

3
这个答案假设comp.Id是一个Guid,而且您没有做任何不寻常的事情,比如使用两个参数的自定义Equals()重载或使用与System.Guid不同的自定义Guid类型。
您的第一行将调用静态方法object.Equals(object objA, object objB)。该方法检查null(在这里不相关,因为Guid永远不可能是null),然后调用objA.Equals(objB)。由于Guid覆盖object.Equals(object),因此将调用该方法。该方法比较两个Guid值是否相等(假设参数确实是Guid,这里是)。
您的第二行将调用重载的operator == for Guid。它再次比较两个Guid是否相等。
这意味着这两种方法将产生相同的结果。主要区别在于,第一行使用object,这意味着您的两个Guid都必须装箱。而这样做可能会对性能产生负面影响。因此,在这种情况下,我建议使用==

1
基于这里的源代码,以下是两个函数的源代码(假设comp.ID是一个Guid,您的EqualsGuid.Equals,当然没有被重载)。它们似乎以完全相同的方式工作。
    public bool Equals(Guid g)
    {
        // Now compare each of the elements
        if(g._a != _a)
            return false;
        if(g._b != _b)
            return false;
        if(g._c != _c)
            return false;
        if (g._d != _d)
            return false;
        if (g._e != _e)
            return false;
        if (g._f != _f)
            return false;
        if (g._g != _g)
            return false;
        if (g._h != _h)
            return false;
        if (g._i != _i)
            return false;
        if (g._j != _j)
            return false;
        if (g._k != _k)
            return false;

        return true;
    }

 public static bool operator ==(Guid a, Guid b)
    {
        // Now compare each of the elements
        if(a._a != b._a)
            return false;
        if(a._b != b._b)
            return false;
        if(a._c != b._c)
            return false;
        if(a._d != b._d)
            return false;
        if(a._e != b._e)
            return false;
        if(a._f != b._f)
            return false;
        if(a._g != b._g)
            return false;
        if(a._h != b._h)
            return false;
        if(a._i != b._i)
            return false;
        if(a._j != b._j)
            return false;
        if(a._k != b._k)
            return false;

        return true;
    }

编辑:如果你正在使用svick提供的object.Equals方法,最后一行会这样说明:

如果两个对象不代表同一个对象引用并且都不为空,则调用objA.Equals(objB)并返回结果。这意味着如果objA重写了Object.Equals(Object)方法,则会调用此覆盖。

Guid确实有一个重载的Equals(object)方法,让我们来看一下源代码:

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
        if(g._a != _a)
            return false;
        if(g._b != _b)
            return false;
        if(g._c != _c)
            return false;
        if (g._d != _d)
            return false;
        if (g._e != _e)
            return false;
        if (g._f != _f)
            return false;
        if (g._g != _g)
            return false;
        if (g._h != _h)
            return false;
        if (g._i != _i)
            return false;
        if (g._j != _j)
            return false;
        if (g._k != _k)
            return false;

        return true;
    }

正如我们所看到的,这个函数检查传递的对象是否实际上是一个Guid(这将不能与 Guid== 重载一起使用,因此这是无意义的),然后执行与 Equals(Guid) 相同的操作(实际上,看起来是复制了实现,因为即使注释也相同,并且不太适合 Equals(Guid))。

因此,最终的答案似乎是,假设两个对象都是 Guids,只有在两个对象都为 null 的情况下,Equals 返回与 operator== 不同的结果:前者将返回 true,而后者将(我想)抛出空引用异常。


Equals 怎么可能是 Guid.Equals?它没有接受两个参数的重载。我认为很明显应该是 object.Equals(object, object) - svick

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