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

时间:2015-09-26 15:41:06

标签: c#

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

我正在使用我创建的一个名为“Pair”的类型但是,我正在尝试使用C#中的contains函数来比较这两种类型但是,我在类型“Pair”中使用了override来比较比较两个Pair对象的“ToString()”。所以有4个字符串进行比较。两个键和两个值。如果两个键相等,则比较两个值。这是有道理的原因是密钥是被攻击的位置(值)的起始(关键)位置。如果键和值相同,则不应添加对象。

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( )使用泛型类型。

2 个答案:

答案 0 :(得分:3)

使用&&并返回相等比较的值,而不是所有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);
}

答案 1 :(得分:1)

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

Tuple类除了为您提供将多个值捆绑在一起的简单方法之外,还自动实现结构相等性,这意味着Tuple对象在以下情况下等于另一个:

  
      
  • 这是一个元组对象。

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

  •   
  • 它的两个组件与当前实例的组件相同。等式由每个组件的默认对象相等比较器确定。

  •   

from MSDN

这意味着您不必将Pair比作其值,而是将责任委托给Tuple中保留的类型。

相关问题