简体   繁体   English

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

[英]C# List comparison between custom objects

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

I'm using a Type I have created called "Pair" but, I'm trying to use the contains function in C# that would compare the two types but, I have used override in the Type "Pair" itself to compare the "ToString()" of both Pair objects being compared. 我使用的是我创建的“对”类型,但是,我试图在C#中使用包含功能来比较这两种类型,但是,我在“对”类型本身中使用了覆盖功能来比较“ ToString”比较两个对对象的()。 So there are 4 strings being compared. 因此,有4个字符串被比较。 The two Keys and two value. 两个键和两个值。 If the two Keys are equal, then the two values are compared. 如果两个键相等,则比较两个值。 The reason why this makes sense is the Key is the originating(key) location for the location(value) being attacked. 之所以说这是合理的原因,是因为密钥是被攻击位置(值)的始发(密钥)位置。 If the key and value are the same then the object should not be added. 如果键和值相同,则不应添加对象。

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;
    }
}

The question is, Is there a better way to do this that doesn't involve stupid amounts of code or creating new objects for dealing with this. 问题是,是否有更好的方法来执行此操作,而不会涉及愚蠢的代码量或创建用于处理此问题的新对象。 Of course if any ideas involve these, I am all ears. 当然,如果有任何想法涉及到这些,我会非常高兴。 The part that confuses me about this is, perhaps I dont understand what is going on but, I was hoping that C# offered a method that just equivalence of values and not the object memory locations and etc. 令我感到困惑的部分是,也许我不了解发生了什么,但是我希望C#提供的方法只是值的等效,而不是对象内存位置等。

I've just ported this from Java as well, and it works exactly the same but, I'm asking this question for C# because I'm hoping there was a better way for me to compare these objects without using ToString() with generic Types. 我也刚刚从Java移植了它,并且它的工作原理完全相同,但是我问这个问题是关于C#的问题,因为我希望有一种更好的方法来比较这些对象,而无需将ToString()与泛型一起使用类型。

You can definitely make this code a lot simpler by using && and just returning the value of equality comparisons, instead of all those if statements and return true; 您绝对可以通过使用&&并返回相等比较的值,而不是所有if语句和return true;使此代码简单得多return true; or return false; return false; statements. 陈述。

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();
}

In Java you could use equals rather than compareTo . 在Java中,您可以使用equals而不是compareTo

Note that these aren't exactly the same as == (and Equals ) use an ordinal comparison rather than a culture-sensitive one - but I suspect that's what you want anyway. 请注意,这些与== (和Equals )使用序数比较而不是对文化敏感的比较并不完全相同 -但我怀疑这仍然是您想要的。

I would personally shy away from comparing the values by ToString() representations. 我个人会回避通过ToString()表示比较值。 I would use the natural equality comparisons of the key and value types instead: 我将使用键和值类型的自然相等比较:

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);
}

(As Avner notes, you could just use Tuple of course...) (正如Avner所述,您当然可以只使用Tuple ...)

As noted in comments, I'd also strongly recommend that you start using properties and C# naming conventions, eg: 如评论中所述,我也强烈建议您开始使用属性和C#命名约定,例如:

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

The simplest way to improve this is to use, instead of your custom Pair class, an instance of the built-in Tuple<T1,T2> class. 改善此问题的最简单方法是使用内置的Tuple<T1,T2>类的实例代替您的自定义Pair类。

The Tuple class, in addition to giving you an easy way to bundle several values together, automatically implements structural equality, meaning that a Tuple object is equal to another if: Tuple类除了为您提供将多个值捆绑在一起的简便方法之外,还自动实现结构相等,这意味着在以下情况下, Tuple对象与另一个对象相等:

  • It is a Tuple object. 它是一个元组对象。

  • Its two components are of the same types as the current instance. 它的两个组件与当前实例具有相同的类型。

  • Its two components are equal to those of the current instance. 它的两个分量等于当前实例的两个分量。 Equality is determined by the default object equality comparer for each component. 平等由每个组件的默认对象平等比较器确定。

( from MSDN ) 来自MSDN

This means that instead of your Pair having to compare its values, you're delegating the responsibility to the types held in the Tuple . 这意味着您不必将Pair值进行比较,而是将责任委托给Tuple的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM