C# 为什么ReferenceEquals仍然与值类型一起使用?

C# 为什么ReferenceEquals仍然与值类型一起使用?,c#,referenceequals,C#,Referenceequals,有一个很好的解释,为什么object.referenceequals,obj不能用于值类型: 使用ReferenceEquals比较值时,如果objA和objB为 值类型,它们在传递给 ReferenceEquals方法。这意味着即使objA和objB 表示值类型的同一实例,ReferenceEquals 方法仍然返回false 但是,我发现代码类似于以下代码段: internal readonly struct Foo { public override bool Equals(obj

有一个很好的解释,为什么object.referenceequals,obj不能用于值类型:

使用ReferenceEquals比较值时,如果objA和objB为 值类型,它们在传递给 ReferenceEquals方法。这意味着即使objA和objB 表示值类型的同一实例,ReferenceEquals 方法仍然返回false

但是,我发现代码类似于以下代码段:

internal readonly struct Foo
{
    public override bool Equals(object obj)
    {
        if (object.ReferenceEquals(this, obj))
        {
            return true;
        }

        if (obj is Foo other)
        {
            return this.Equals(other);
        }

        return false;
    }

    public bool Equals(Foo other)
    {
        // ..
        return true;
    }
}

这是错误的还是存在一种边缘情况,在这种情况下,ReferenceEquals可能很有用,即对于值类型,尤其是结构,求值为true?

不应该是这样。编写的代码很糟糕,因为它不必要地为一个永远不会工作的测试装箱。为了完整起见,在这种情况下,更有用和惯用的模式是:

//自定义Foo平等实现 公共学校与其他学校同等 { // ... } //默认对象实现 公共重写int GetHashCode{…}//必须与EqualsFoo逻辑匹配 public override bool Equalsobject obj=>obj是Foo-other&&Equalsother;
不应该这样。编写的代码很糟糕,因为它不必要地为一个永远不会工作的测试装箱。为了完整起见,在这种情况下,更有用和惯用的模式是:

//自定义Foo平等实现 公共学校与其他学校同等 { // ... } //默认对象实现 公共重写int GetHashCode{…}//必须与EqualsFoo逻辑匹配 public override bool Equalsobject obj=>obj是Foo-other&&Equalsother;
是的,只是错了。Foo是一种值类型,因此将其传递给object.ReferenceEquals会将实例本身框起来。新装箱的实例不能等于任何值,因为在调用EqualObject之前该引用从未存在。是的,它是错误的。它生成的StackOverflowException确保它不会被使用。假设这里没有不包含的EqualsFoo。我想如果存在重载bool EqualsFoo obj,它可能不会抛出StackOverflowException。我猜。是的,这里省略了EqualsFoo obj实现。是的,它只是错了。Foo是一种值类型,因此将其传递给object.ReferenceEquals会将实例本身框起来。新装箱的实例不能等于任何值,因为在调用EqualObject之前该引用从未存在。是的,它是错误的。它生成的StackOverflowException确保它不会被使用。假设这里没有不包含的EqualsFoo。我想如果存在重载bool EqualsFoo obj,它可能不会抛出StackOverflowException。我猜。是的,这里省略了EqualsFoo obj实现。