C# 在结构中,通过Equals实现运算符==是否有效,但不重写Equals和GetHashCode吗?

C# 在结构中,通过Equals实现运算符==是否有效,但不重写Equals和GetHashCode吗?,c#,.net,operator-overloading,equals,equals-operator,C#,.net,Operator Overloading,Equals,Equals Operator,这有效吗 public struct MyStruct { public int Foo { get; set; } public static bool operator ==(MyStruct a, MyStruct b) { return a.Equals(b); } public static bool operator !=(MyStruct a, MyStruct b) { return !a.Equ

这有效吗

public struct MyStruct
{
    public int Foo { get; set; }

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

    public static bool operator !=(MyStruct a, MyStruct b)
    {
        return !a.Equals(b);
    }
}
(我知道这有点低效,因为Object.Equals默认情况下对值类型使用反射。但它有效吗?)


我这样问是因为ReSharper突出显示了它并警告我,
MyStruct定义运算符'=='或运算符'!='但不提供“Object.Equals(Object o)”和“Object.GetHashCode()”

有效吗?对但它并不能给你买任何东西。

从编译的事实来看,它是有效的。但它是“无效的”,因为它打破了类用户的所有期望-框架设计指南规定,您不应该实现只存在于运算符重载中的功能-这些方法应该以其他方式访问。标准是Object.Equals和operator==实现相同的功能

:

提供备用签名。最 语言不支持运算符 超载。出于这个原因,这是一个很好的选择 所有类型的CLS要求 重载运算符以包括 第二种方法具有适当的 提供 等效功能。这是一个 公共语言规范(CLS) 提供此二级服务的要求 方法。下面的例子是 符合CLS标准


我想这可能很有趣

它让我能够通过“==”比较两个MyStruct实例,不是吗?@Stefan:什么,你讨厌键入
等于
?;)我的意思是它不会给你买任何你没有的东西(使用
等于
)。通常使用
struct
编写相等逻辑以获得性能优势是一个好主意;但根据你对反思的评论,听起来你已经知道了。所以,如果你真的更喜欢
=
而不是
等于
,但要明白它实际上并没有给你除此之外的任何东西。。。是的,我确实更喜欢==而不是Equals,因为我喜欢像对待基本类型一样对待我的值类型。谢谢。@Stefan:完全合理。我仍然建议重写
Equals
,以避免反射开销。但那只是我。警告是因为Damien所说的:它违背了开发人员的期望。在Foo{get;set;}中,setter有点奇怪。值类型应该是不可变的,setter只是在一个非常复杂的(无用的)更新网络中愚弄您。如果结构中的单个值发生更改,只需创建一个完整的新结构。e、 g:点是一个结构。不能改变点的X或Y。因为点是“静态”实体,所以不能“移动”它们。如果一个点发生变化,它必须是另一个点,即新结构。结论:将所有属性设置为只读,并仅通过构造函数传递值。卡斯帕:人们一直这么说,但我强烈反对。如果我将setter设置为私有,struct Point的用户只需更改他们的
p.X++到可读性较差的
p=新点(p.X+1,p.Y)p=p.WithX(p.X+1)这样奇怪的东西,没有任何好处。不可变值类型的好处不仅仅与语法有关。这是因为它们比可变值类型更容易推理。埃里克·利珀特可能比任何人都能更好地解释这一点。然而,如果你意识到了这些邪恶,并且未来与你的可变值类型交互的每个人都同意,那就去做吧。@Alex Humphrey:可变值类型很好,只要它们永远不会变异“this”,也就是说,改变它们的唯一方法要么是通过公共可变字段,要么是通过修改通过引用传递的结构的公共方法。net对它们的处理有一些限制(特别是属性),但是可以通过定义一个Holder类来克服这些限制,该类包含一个T类型的公共字段。我相信我没有违反这些准则。对于我的结构,Object.Equals和operator==实现相同的功能,因为后者只调用前者。@Stefan:没错。但是ReSharper不知道您已经以这种方式“链接”了这些方法。我认为一般来说,当你看到
==
时=运算符已经为一个类型实现,您希望看到
Equals
(因此
GetHashCode
)被覆盖。谢谢。浮动问题很小,但值得了解。