C# - 无法重写 ==

3
我有以下类(为Unity游戏引擎构建):
using System;
using System.Collections.Generic;
using UnityEngine;

public class Biome : ScriptableObject, IEquatable<Biome>
{
    // ...

    //
    // IEquatable
    //

    public bool Equals(Biome other)
    {
        if (other == null)
            return false;

        return this.name == other.name;
    }

    public override bool Equals(object obj)
    {
        if (obj == null) return false;

        Biome other = obj as Biome;

        if (other == null) return false;

        return Equals(other);
    }

    public override int GetHashCode()
    {
        return this.name.GetHashCode();
    }

    public static bool operator ==(Biome biome1, Biome biome2)
    {
        if (object.ReferenceEquals(biome1, biome2)) return true;
        if (object.ReferenceEquals(null, biome1)) return false;
        if (object.ReferenceEquals(null, biome2)) return false;

        return biome1.Equals(biome2);
    }

    public static bool operator !=(Biome biome1, Biome biome2)
    {
        if (object.ReferenceEquals(biome1, biome2)) return false;
        if (object.ReferenceEquals(biome1, null)) return true;
        if (object.ReferenceEquals(biome2, null)) return true;

        return !biome1.Equals(biome2);
    }
}

当我尝试进行测试时,函数Equals似乎有效,但运算符==给了我不同的结果。

    [Test]
    public void FooTest()
    {
        ScriptableObject biome1 = ScriptableObject.CreateInstance("Biome");
        ScriptableObject biome2 = ScriptableObject.CreateInstance("Biome");

        biome1.name = "Biome #1";
        biome2.name = "Biome #1";

        Assert.IsTrue(biome1.Equals(biome2));
        Assert.IsTrue(biome1 == biome2);  // This one fails

    }

我实现有什么问题吗?
更新:如果有影响,这里是完整的类:https://www.hastebin.com/divazubero.cpp

1
FYI,!= 的典型实现仅为 return !(a == b) - juharr
3
你进行了调试吗?请注意,if (other == null) 会再次调用你的 == 运算符。 - René Vogt
那么编译器在你传递既是Biome()又是对象的生物群落时,如何确定使用哪个Equals方法呢?如果这不是主题,我很抱歉,因为我从未遇到过这种情况。 - emsimpson92
3
我抽出时间复制了你的代码并测试了一下...对我来说它能正常运行...两次调用都返回true。所以似乎还有更多与这个问题相关的代码或信息。 - René Vogt
2
很抱歉,复制时犯了一个小错误...我的测试变量都是Biome类型。如果它们是“object”,我就能得到你的结果。看来@emsimpson92是有道理的。 - René Vogt
显示剩余3条评论
1个回答

8
问题在于你的变量类型为 ScriptableObject,而不是 Biome。
编译器必须在编译时决定调用哪个重载。由于它在编译时不知道运行时类型将是 Biome,因此它会发出对 ScriptableObject 的 == 运算符的调用。 如果该类没有重写的 == 运算符,则调用 object 的运算符(执行简单的 ReferenceEquals,当然为 false)。
== 运算符重载不是虚拟的。
如果在测试中使用特定类型 Biome,则可以按预期工作。

确实,那就是问题所在。尽管我尝试进行强制类型转换时出现编译错误,但我不确定原因。但这确实是断言失败的原因。 - Enrique Moreno Tent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接