c#列表中自定义对象之间的比较

本文关键字:之间 比较 对象 自定义 列表 | 更新日期: 2023-09-27 18:14:50

Pair<BoardLocation, BoardLocation> loc = new Pair<BoardLocation, BoardLocation>( this.getLocation(), l );
if(!this.getPlayer().getMoves().Contains( loc )) {
    this.getPlayer().addMove( loc );
}

我正在使用我创建的名为"Pair"的类型,但是,我试图使用c#中的包含函数来比较这两种类型,但是,我已经在类型"Pair"本身中使用了覆盖来比较正在比较的两个Pair对象的"ToString()"。有4个字符串被比较。两个键和两个值。如果两个key相等,则比较这两个值。这之所以有意义,是因为密钥是被攻击位置(值)的原始(密钥)位置。如果键和值相同,则不应添加对象。

public override bool Equals( object obj ) {
    Pair<K, V> objNode = (Pair<K, V>)obj;
    if(this.value.ToString().CompareTo( objNode.value.ToString() ) == 0) {
        if(this.key.ToString().CompareTo( objNode.key.ToString() ) == 0) {
            return true;
        } else
            return false;
    } else {
        return false;
    }
}

问题是,有没有更好的方法来做到这一点,不涉及愚蠢的代码量或创建新的对象来处理这个。当然,如果有任何想法涉及这些,我洗耳恭听。让我感到困惑的部分是,也许我不明白发生了什么,但是,我希望c#提供了一种方法,只是等价的值,而不是对象内存位置等。

我刚刚从Java移植了这个,它的工作原理完全相同,但是,我问这个问题对于c#,因为我希望有一个更好的方法来比较这些对象,而不使用ToString()与泛型类型

c#列表中自定义对象之间的比较

您可以通过使用&&并只返回相等比较的值,而不是所有这些if语句和return true;return false;语句,使这段代码变得简单得多。

public override bool Equals (object obj) {
    // Safety first: handle the case where the other object isn't
    // of the same type, or obj is null. In both cases we should
    // return false, rather than throwing an exception
    Pair<K, V> otherPair = objNode as Pair<K, V>;
    if (otherPair == null) {
        return false;
    }
    return key.ToString() == otherPair.key.ToString() &&
        value.ToString() == otherPair.value.ToString();
}

在Java中你可以使用equals而不是compareTo

请注意,这些==(和Equals)不完全相同,使用顺序比较而不是文化敏感的比较-但我怀疑无论如何都是您想要的。

我个人会避免比较ToString()表示的值。我将使用键和值类型的自然相等比较:

public override bool Equals (object obj) {
    // Safety first: handle the case where the other object isn't
    // of the same type, or obj is null. In both cases we should
    // return false, rather than throwing an exception
    Pair<K, V> otherPair = objNode as Pair<K, V>;
    if (otherPair == null) {
        return false;
    }
    return EqualityComparer<K>.Default.Equals(key, otherPair.key) &&
        EqualityComparer<K>.Default.Equals(value, otherPair.value);
}

(正如Avner所指出的,您当然可以使用Tuple…)

正如在注释中提到的,我还强烈建议你开始使用属性和c#命名约定,例如:

if (!Player.Moves.Contains(loc)) {
    Player.AddMove(loc);
}

最简单的改进方法是使用内置Tuple<T1,T2>类的实例,而不是使用自定义Pair类。

Tuple类,除了给你一个简单的方法把几个值捆绑在一起,自动实现结构相等,这意味着一个Tuple对象等于另一个if:

  • 是一个Tuple对象

  • 它的两个组件与当前实例的类型相同

  • 它的两个组件等于当前实例的组件。相等性由每个组件的默认对象相等比较器决定。

从MSDN

这意味着你的Pair不必比较它的值,你将责任委托给Tuple中持有的类型。