Domanda

Ho una classe Person, IT ATTUALMENTE equivale () Metodo da IEquatable<Person> (Sostituisce anche il metodo Object.Equals, consente di ignorare il metodo GetHashCode () per ora)

class Person : IEquatable<Person>
{
    public string Name { get; set; }

    public bool Equals(Person other)
    {
        return this.Name == other.Name;
    }
    public override bool Equals(object obj)
    {
        var person = obj as Person;
        return person != null && person.Name == Name;
    }
}
.

OK, inizia:

Person p1 = new Person() { Name = "a" };
Person p2 = new Person() { Name = "a" };

List<Person> lst1 = new List<Person>() { p1 };
List<Person> lst2 = new List<Person>() { p2 };
.

Lascia parlare di questa linea:

 bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default);
.

Ho un problema Comprendere questa parte:

EqualityComparer<Person>.Default
.

Ho sentito che EqualityComparer<Person>.Default controllerà se la classe implementerà IEquatable - prenderà il metodo Equals(Person other) e non il Equals(object obj). ha il vantaggio di evitare il boxe

Inserire la descrizione dell'immagine qui Ma

Il Equals(Person other) eseguirà con o senza EqualityComparer<Person>.Default (perché è implementato i equiacking)

Allora di quale boxe stiamo parlando? Non c'è!

L'unica volta in cui Equals(object obj) verrà eseguito è quando:

bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default);
.

Ma Sono un programmatore! Non inviare mai un object quando è in realtà un Person!

Cosa mi manca? Ho difficoltà a capire il beneficio qui di EqualityComparer<Object>.Default. Qualcuno può per favore darmi un esempio per dimostrarmi che mi sbaglio?

È stato utile?

Soluzione

If you pass in null as the second parameter or if you don't pass in a second argument at all (which is basically the same), the implementation of SequenceEquals will call EqualityComparer<T>.Default itself (decompile Enumerable to see this). That explains why you don't see a difference whether you provide EqualityComparer<T>.Default or not.

So in the end the second parameter only makes sense if you want to use an equality comparer other than EqualityComparer<T>.Default.

Altri suggerimenti

That you can pass in IEqualityComparer<object>.Default is an effect of generic contravariance, added in .NET 4.

Essentially, an IEqualityComparer<BaseType> can be used whenever an IEqualityComparer<DerivedType> is required, where DerivedType : BaseType. Since Person derives from Object, this means that an IEqualityComparer<Object> can be used wherever an IEqualityComparer<Person> is required.

The answer is here: http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

For a value type, you should always implement IEquatable and override Object.Equals(Object) for better performance. Object.Equals boxes value types and relies on reflection to compare two values for equality. Both your implementation of Equals and your override of Object.Equals should return consistent results.

If you do not override Equals and GetHashCode, EqualityComparer.Default actually takes care of that for you.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top