You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何通过反射判断Record是否实现自定义相等比较方法

C# Record类型自定义Equals方法的反射判断方案

完全可以通过反射实现该判断,核心是识别编译器自动生成代码的专属标记。

实现原理

C#编译器为无自定义相等逻辑的Record类型自动生成相等比较相关方法时,会遵循固定规则:

  • 自动生成的强类型Equals(TRecord other)方法(IEquatable<T>接口实现)、Equals(object? obj)重写方法、GetHashCode()重写方法,都会被标记[CompilerGenerated]特性
  • 如果开发者显式实现了任意签名匹配的相等比较方法,编译器就不会生成对应签名的自动实现方法,开发者手写的方法默认不会携带[CompilerGenerated]特性

通过检查Record类型上强类型Equals方法是否携带该特性,即可准确区分是编译器自动生成还是用户自定义实现。

实现代码

首先引入必须的命名空间:

using System.Reflection;
using System.Runtime.CompilerServices;

判断方法实现如下:

public static bool HasCustomEqualityImplementation(Type recordType)
{
    // 非Record类型直接返回false,可按需调整为抛出参数异常
    if (!recordType.IsRecord)
        return false;

    // 查找当前类型自身声明的强类型Equals方法:public bool Equals(当前记录类型 other)
    // DeclaredOnly 标记指定只查找当前类型定义的成员,不查找从父类继承的成员
    MethodInfo? strongTypedEquals = recordType.GetMethod(
        nameof(object.Equals),
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
        binder: null,
        new[] { recordType },
        modifiers: null);

    // 正常无自定义逻辑的Record一定会存在编译器生成的强类型Equals方法,若不存在则判定为自定义实现
    if (strongTypedEquals == null)
        return true;

    // 方法未携带CompilerGenerated特性即为用户自定义实现
    return !strongTypedEquals.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false);
}

结果验证

针对题目给出的示例代码,调用结果完全符合预期:

HasCustomEqualityImplementation(typeof(A)); // 返回false,A的Equals为编译器自动生成,带[CompilerGenerated]标记
HasCustomEqualityImplementation(typeof(B)); // 返回true,B的Equals为用户手写实现,无编译器生成标记

补充说明

  • 该方案依赖C#编译器的代码生成约定,常规业务开发中不会有开发者手动为自定义方法添加[CompilerGenerated]特性,判断可靠性极高
  • 若需要覆盖极端场景(比如用户仅重写了Equals(object?)或GetHashCode()、未定义强类型Equals方法),可以在判断逻辑中追加对这两个方法的[CompilerGenerated]特性检查,只要任意一个相等相关方法没有该标记,就判定为存在自定义实现
  • 该方案支持所有.NET 5及以上版本(Record类型从.NET 5开始正式引入)

内容的提问来源于stack exchange,提问作者Julien Barrau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:21:24