替换C#记录结构的合成Equals()

问题描述 投票:0回答:1

简而言之:

有什么方法可以为

Equals( object? )
提供我自己的
record struct
方法,而不是被编译器自动生成的方法困住吗?

注:

本题与替换自动生成的

MyRecord.Equals( MyRecord )
方法无关,这很简单;这个问题具体是关于替换从
MyRecord.Equals( Object? )
继承的
Object
方法,这是一个完全不同的故事。

背景:

编程语言设计者为我们提供了这些美妙的强类型语言来编写健壮的代码,然后他们向它们添加了构思不佳的小功能,这些功能否定了强类型并武装我们的手射击我们的脚。

C# 中此类功能的一个示例是

object.Equals( object? )
,这使得这种其他类型的强类型语言完全能够像这样编译废话:
myColor.Equals( "string" )
而不会出现丝毫错误。

为了稍微缓解这个问题,在我需要覆盖的每个类中

object.Equals( object? )
我确保用
[System.Obsolete]
声明它,这样它就不会被意外调用。 (当然,我还必须禁用 CS0809 警告“Obsolete member overrides non-obsolete member”,因为显然,在覆盖它们时过时的成员是完全没问题的,甚至是非常可取的。)

这适用于普通的旧

class
struct
;不幸的是,它不再适用于
record
; IDE 说“已经声明了具有相同签名的成员”,编译器给出了“错误 CS0111:类型‘Color’已经定义了一个名为‘Equals’的具有相同参数类型的成员”。

快速查看官方 Microsoft 文档herehere说这是设计使然。

问题:

有人知道解决这个问题的方法吗?

(除了从不使用

record
并丧失其所有便利性。)

c# struct record equality
1个回答
0
投票
  1. 有什么方法可以为记录结构提供我自己的 `Equals(object?) 方法,而不是被编译器自动生成的方法卡住?

    不,它不是,因为记录结构spec说:

    record 结构包含一个合成覆盖,相当于声明如下的方法:

    public override readonly bool Equals(object? obj);
    

    显式声明覆盖是错误的

  2. 有人知道解决这个问题的方法吗?

    您可以尝试使用 Fody 来研究一些程序集编织,但据我所知,这是在编译后发生的,因此它不会涵盖所有可能的场景(即不适用于相同的程序集用法)。

    就我个人而言,我会考虑放弃

    ObsoleteAttribute
    方法并尝试实施 Roslyn 分析器 它将处理您要解决的类型不匹配问题。

© www.soinside.com 2019 - 2024. All rights reserved.