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

从C#调用F#记录类型时的结构相等性实现问题

问题解答:在C#中为F#记录类型启用运算符的结构相等性

你遇到的问题核心在于:F#记录默认只实现了基于Equals的结构相等,但没有自动为C#重载==和!=运算符。不过我们可以通过在F#代码里手动添加运算符重载,让C#里的==/!=也能实现结构相等判断。

为什么默认C#里==会失败?

F#的记录类型默认会:

  • 实现IEquatable<Rating>接口
  • 重写Object.Equals方法来做结构相等比较
  • 但F#本身用=表示值相等,===表示引用相等,所以默认生成的IL代码里没有定义op_Equality(对应==)和op_Inequality(对应!=)这两个静态运算符。

而C#里的==运算符,对于引用类型默认是做引用相等判断,所以你的C#测试里a == b会返回false,和ReferenceEquals结果一致,这就是前两个断言失败的原因。

解决方案:在F#记录中手动重载运算符

只需要在F#的记录定义里添加==和!=的静态运算符重载,就能让C#调用这些运算符时使用结构相等逻辑:

type Rating = { 
    Id : string 
    AverageRating : decimal 
    ValueRange : int 
    Label : string 
} with
    // 重载 == 运算符
    static member op_Equality(a: Rating, b: Rating) =
        a.Equals(b)
    // 重载 != 运算符
    static member op_Inequality(a: Rating, b: Rating) =
        not (a.Equals(b))

验证修改后的效果

修改后再运行你的C#测试:

  • Assert.True(a == b):会调用我们重载的op_Equality,使用结构相等判断,返回true
  • Assert.False(a != b):同理调用op_Inequality,返回false
  • Assert.True(a.Equals(b))和Assert.False(ReferenceEquals(a, b))的行为和之前保持一致,不会受影响

这样就实现了你想要的:在C#里通过==/!=运算符获得F#记录默认的结构相等性,不需要每次都显式调用Equals()。

内容的提问来源于stack exchange,提问作者Dave Cook

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:23:15