سؤال

أحاول مقارنة النوع المخصص في اثنين List<T> واستخدام Intersect / Except طريقة.يتم تحديد المساواة من خلال ثلاثة مجالات من هذا النوع.المساواة مبنية على أكثر من الشرط العادي (جميع الحقول تحتوي على نفس البيانات).لقد نفذت بالطبع IEqualityComparer<T>.مشكلتي هي أن GetHashCode() لا تعود الطريقة متساوية بمجرد أن يكون رمز التجزئة ليس هو نفسه وهذا لا يساعدني لأن هذا غير صحيح في حالتي.

هل هناك أي طريقة لمقارنة كائنين مخصصين عندما تعتمد المساواة على أكثر من شرط واحد حتى أتمكن من استخدام التقاطع/باستثناء/المتميز وما إلى ذلك...؟

هنا هو الكود الخاص بي:

public bool Equals(ComparableObject x, ComparableObject y)
{
    if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
        return false;

    if (Object.ReferenceEquals(x, y))
        return true;

    if (x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;

    if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return true;


    if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;

    if (!x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return true;

    if (x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return false;

    if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && x.Var2.Equals(y.Var2))
        return false;

    if (!x.Var1.Equals(y.Var1) && !x.Var3.Equals(y.Var3) && !x.Var2.Equals(y.Var2))
        return false;


    return x.Var1.Equals(y.Var1) && x.Var1.Equals(y.Var1) && x.Var3.Equals(y.Var3);
}


public int GetHashCode(ComparableObject x)
{
    return obj.Var1.GetHashCode() ^ obj.Var2.GetHashCode()^ obj.Var3.GetHashCode()
}
هل كانت مفيدة؟

المحلول

ومن عملك لتوفير مثل هذا GetHashCode() أن القيمة التي ترجعها ستكون مختلفة بالنسبة للكائنات التي نكون مختلفة (في أكبر عدد ممكن من الحالات؛لا يزال بإمكانك إرجاع رمز التجزئة نفسه للكائنات غير المتساوية)، وسيكون دائمًا هو نفسه بالنسبة للكائنات التي يمكن تكون متساوية (في جميع الحالات؛لا يجوز لك إرجاع رمز تجزئة مختلف للكائنات المتساوية).

على سبيل المثال، إذا كان أحد الحقول الثلاثة التي تقارنها هو int, ، يمكنك إرجاع هذا الحقل كـ GetHashCode().

ومع ذلك، إذا كان من الصعب التوصل إلى شيء ذكي، فيمكنك إرجاع ثابت، مثل 42.من هنا Equals() سيتم استدعاؤه لجميع أزواج الكائنات، مما يوفر النتائج المتوقعة، على الرغم من أنه بطريقة أقل أداءً.

نصائح أخرى

لست متأكدًا مما إذا كانت لديك مشكلات أخرى مع GetHashCode في الأنواع الأساسية لديك، ولكن هذا مثال لنوع مخصص وIEqualityComparer الذي يُرجع صحيحًا إذا كان الحقلان الأولان فقط متماثلين.وهذا سيسمح Except إلخ.للعمل على النوع.

    public class CustomType
    {
        public int Val1 { get; set; }
        public int Val2 { get; set; }
        public int Val3 { get; set; }
    }

    class CustomTypeComparer : IEqualityComparer<CustomType>
    {
        public bool Equals(CustomType x, CustomType y)
        { return x.Val1 == y.Val1 && x.Val2 == y.Val2; }

        public int GetHashCode(CustomType obj)
        { return obj.Val1.GetHashCode() ^ obj.Val2.GetHashCode(); }
    }

إذا كانت خصائصك ليست أنواعًا بسيطة مثل int, ، قد ترغب في استخدامها Equals() بدلاً من == لمقارنة الكائنات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top