简体   繁体   中英

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. So there are 4 strings being compared. 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.

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.

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; or 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 .

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.

I would personally shy away from comparing the values by ToString() representations. 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...)

As noted in comments, I'd also strongly recommend that you start using properties and C# naming conventions, eg:

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.

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:

  • 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 )

This means that instead of your Pair having to compare its values, you're delegating the responsibility to the types held in the Tuple .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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