EqualityComparer<T>.هل هناك سوء فهم افتراضي؟
-
11-12-2019 - |
سؤال
عندي حصة دراسية Person
, ، فهو يطبق طريقة Equals() من IEquatable<Person>
(يتجاوز أيضًا Object.Equals
الطريقة، فلنتجاهل طريقة GetHashcode() في الوقت الحالي)
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;
}
}
حسنا لنبدأ:
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 };
لنتحدث عن هذا الخط :
bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default);
لدي مشكلة في فهم هذا الجزء:
EqualityComparer<Person>.Default
لقد سمعت أن EqualityComparer<Person>.Default
سوف تحقق مما إذا كان الفصل يتم تنفيذه IEquatable
- سوف يستغرق Equals(Person other)
الطريقة وليس Equals(object obj)
. لديها ميزة تجنب الملاكمة
لكن
ال Equals(Person other)
سيتم تشغيل مع أو بدون EqualityComparer<Person>.Default
(لأنها تنفذ IEquatable)
إذن ما هي الملاكمة التي نتحدث عنها؟لا يوجد !
المرة الوحيدة التي Equals(object obj)
سيتم تشغيله عندما:
bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default);
لكن أنا مبرمج!لن أرسل أبدًا object
عندما يكون في الواقع أ Person
!
ماذا ينقصني؟أجد صعوبة في فهم الفائدة هنا EqualityComparer<Object>.Default
.هل يمكن لأحد أن يعطيني مثالاً ليثبت أنني مخطئ؟
المحلول
إذا قمت بالمرور null
كمعلمة ثانية أو إذا لم تقم بتمرير وسيطة ثانية على الإطلاق (والتي هي نفسها في الأساس)، فسيتم استدعاء تطبيق SequenceEquals EqualityComparer<T>.Default
نفسها (تفكيك Enumerable
لرؤية هذا).وهذا ما يفسر سبب عدم رؤيتك للفرق سواء قمت بتقديمه EqualityComparer<T>.Default
أم لا.
لذا في النهاية، تكون المعلمة الثانية منطقية فقط إذا كنت تريد استخدام مقارن المساواة غير ذلك EqualityComparer<T>.Default
.
نصائح أخرى
أنه يمكنك المرور IEqualityComparer<object>.Default
هو تأثير التناقض العام, تمت إضافته في .NET 4.
في الأساس، أ IEqualityComparer<BaseType>
يمكن استخدامها كلما IEqualityComparer<DerivedType>
مطلوب، حيث DerivedType : BaseType
.منذ Person
مشتق من Object
, ، وهذا يعني أن IEqualityComparer<Object>
يمكن استخدامها أينما IEqualityComparer<Person>
مطلوب.
الجواب هنا: http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx
بالنسبة لنوع القيمة، يجب عليك دائمًا تطبيق IEquatable وتجاوز Object.Equals(Object) للحصول على أداء أفضل.أنواع قيم مربعات Object.Equals وتعتمد على الانعكاس لمقارنة قيمتين للمساواة.يجب أن يؤدي تطبيقك لـ Equals وتجاوزك لـ Object.Equals إلى نتائج متسقة.
إذا لم تقم بتجاوز Equals وGetHashCode، فإن EqualityComparer.Default يعتني بذلك نيابةً عنك.