【问题标题】:Comparing a class instance with another, which contain matching values将一个类实例与另一个包含匹配值的类实例进行比较
【发布时间】:2019-05-17 07:04:46
【问题描述】:

我知道一个类的一个实例不等于同一个类的另一个实例,即使两个实例都包含属性和实例的字段包含相同的值。例如,在下面的代码中,即使 TestClass 的两个实例的 TestValue01TestValue02 属性的值相同,比较将等于 false 并且将打印 "Boooo!"

static void Main(string[] args)
{
    TestClass testClassInstance01 = new TestClass(1, 1);
    TestClass testClassInstance02 = new TestClass(1, 1);

    if (testClassInstance01 == testClassInstance02)
    {
        Console.WriteLine("Woohoo!");
    }
    else
    {
        Console.WriteLine("Boooo!");
    }
}

class TestClass
{
    public int TestValue01 { get; private set; }
    public int TestValue02 { get; private set; }

    public TestClass(int testValue01, int testValue02)
    {
        TestValue01 = testValue01;
        TestValue02 = testValue02;
    }
}

是否有可能强制这种比较等同于真实?

显而易见的事情是比较属性值,如下所示,但我很好奇这是否可以避免。

if (testClassInstance01.TestValue01 == testClassInstance02.TestValue01
    && testClassInstance01.TestValue02 == testClassInstance02.TestValue02)
{
    Console.WriteLine("Woohoo!");
}
else
{
    Console.WriteLine("Boooo!");
}

编辑

为了完整起见,我正在寻找的是operator overloading。下面是我要求这个例子返回 true 的代码:

class TestClass
{
    public int TestValue01 { get; private set; }
    public int TestValue02 { get; private set; }

    public TestClass(int testValue01, int testValue02)
    {
        TestValue01 = testValue01;
        TestValue02 = testValue02;
    }

    public static bool operator==(TestClass tc01, TestClass tc02)
    {
        return tc01.TestValue01 == tc02.TestValue01 && tc01.TestValue02 == tc02.TestValue02;
    }

    public static bool operator!=(TestClass tc01, TestClass tc02)
    {
        return tc01.TestValue01 != tc02.TestValue01 || tc01.TestValue02 != tc02.TestValue02;
    }
}

【问题讨论】:

标签: c# class comparison


【解决方案1】:

Marij Khans 的回答基本上是正确的。在不重载运算符的情况下,ReferenceEquals(object, object) 在应用于类实例时用于“==”和“!=”,因为在您的示例中您比较了两个实例,因此结果为“假”。完整的解决方案如下所示:

public class TestClass : IEquatable<TestClass>
{
    public int TestValue01 { get; private set; }
    public int TestValue02 { get; private set; }

    public TestClass(int testValue01, int testValue02)
    {
        TestValue01 = testValue01;
        TestValue02 = testValue02;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as TestClass);
    }

    public bool Equals(TestClass other)
    {
        return other != null &&
            TestValue01 == other.TestValue01 &&
            TestValue02 == other.TestValue02;
    }

    public static bool operator ==(TestClass test1, TestClass test2)
    {
        return EqualityComparer<TestClass>.Default.Equals(test1, test2);
    }

    public static bool operator !=(TestClass test1, TestClass test2)
    {
        return !(test1 == test2);
    }
}

除了运算符 '==' 和 '!=' 的重载之外,IEquatable 接口的实现可确保比较始终按预期工作,即使在用作字典中的键或模式 a.Equals(b) 时也是如此用过的。为了在使用此类的实例作为键搜索大型集合时获得更快的速度,您甚至可能想要实现 GetHashCode(),但这要求生成哈希码时使用的值必须是只读的(即删除属性的设置器,所以它们只能在构造函数中设置)。

【讨论】:

    【解决方案2】:

    重载 == 运算符。我有一段时间没用过 c#,所以我有点生疏了,但你可以看看运算符重载来定义这种类型的行为

    【讨论】:

    • 这正是我所追求的,谢谢!有人评论了一个类似的链接,这给了我一个可以效仿的例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多