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

重写ToString()是否会导致自定义类的数值隐式相等比较失效?

断言失败原因
  • 相等性实现不符合C#规范:你声明Outer类实现了IEquatable<decimal>,但实际仅定义了接收Outer类型参数的Equals重载,既没有实现接口要求的Equals(decimal)方法,也没有重写object基类的Equals和GetHashCode方法。
  • NUnit的Assert.AreEqual比较两个引用类型时,默认调用object.Equals方法,该方法的默认逻辑是比较对象的引用地址。你代码中!a返回的是新创建的Outer实例,和b是两个独立对象,引用地址不同,哪怕Value值一致,默认比较也会失败。
  • 额外语法问题:你定义的!运算符存在错误,静态方法中不能直接访问实例字段Value,需要修改为1m - o.Value。
修复方案

按照C#相等性实现规范补全所有相关方法即可,修正后的代码如下:

public class Outer : IEquatable<Outer>
{
    public decimal Value;

    public Outer(decimal val = 0.5m) => Value = val;

    public override string ToString() => $"Value: {Value}";

    // 实现IEquatable<Outer>接口方法
    public bool Equals(Outer other)
    {
        if (other is null) return false;
        return Value == other.Value;
    }

    // 重写object基类Equals方法
    public override bool Equals(object obj)
    {
        return Equals(obj as Outer);
    }

    // 配套重写GetHashCode
    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }

    // 重载相等运算符
    public static bool operator ==(Outer left, Outer right)
    {
        if (left is null) return right is null;
        return left.Equals(right);
    }

    public static bool operator !=(Outer left, Outer right)
    {
        return !(left == right);
    }

    public static implicit operator decimal(Outer o) => o.Value;
    public static implicit operator Outer(decimal d) => new Outer(d);

    // 修复逻辑非运算符错误
    public static Outer operator !(Outer o) => new Outer(1m - o.Value);
}

修改完成后,Assert.AreEqual(b, !a)就会按照Value值判断相等,正常通过测试。

内容的提问来源于stack exchange,提问作者Martin Bocanegra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:24:03