كيف ينبغي أن تذهب عن تنفيذ الكائن.GetHashCode() المعقدة المساواة ؟

StackOverflow https://stackoverflow.com/questions/1072058

سؤال

في الأساس لدي التالية حتى الآن:

class Foo {
    public override bool Equals(object obj)
    {
        Foo d = obj as Foo ;
        if (d == null)
            return false;

        return this.Equals(d);
    }

    #region IEquatable<Foo> Members

    public bool Equals(Foo other)
    {
        if (this.Guid != String.Empty && this.Guid == other.Guid)
            return true;
        else if (this.Guid != String.Empty || other.Guid != String.Empty)
            return false;

        if (this.Title == other.Title &&
            this.PublishDate == other.PublishDate &&
            this.Description == other.Description)
            return true;

        return false;
    }
}

إذن المشكلة هي هذه:لدي غير حقل مطلوب Guid, وهو معرف فريد.إذا لم يكن هذا إذا كنت تحتاج إلى محاولة تحديد المساواة على أساس أقل دقة المقاييس محاولة تحديد ما إذا كان اثنين من الأشياء متساوية.هذا يعمل بشكل جيد ، لكنه جعل GetHashCode() فوضوي...كيف ينبغي أن تذهب نحو ذلك ؟ ساذجة تنفيذ سيكون شيئا مثل:

public override int GetHashCode() {
    if (this.Guid != String.Empty)
        return this.Guid.GetHashCode();

    int hash = 37;
    hash = hash * 23 + this.Title.GetHashCode();
    hash = hash * 23 + this.PublishDate.GetHashCode();
    hash = hash * 23 + this.Description.GetHashCode();
    return hash;
}

ولكن ما هي فرص نوعين من تجزئة الاصطدام?بالتأكيد لم أكن أتوقع أن يكون 1 in 2 ** 32.وهذا هو فكرة سيئة ، وإذا كان الأمر كذلك ، كيف يجب أن أفعل ذلك ؟

هل كانت مفيدة؟

المحلول

وأنا لا أعتقد أن هناك مشكلة مع النهج الذي اخترته للاستخدام. القلق 'الكثير' عن اصطدام التجزئة هو دائما تقريبا مؤشرا على مشكلة التفكير أكثر؛ ما دام من المرجح للغاية أن تكون مختلفة تجزئة يجب أن يكون على ما يرام.

وفي نهاية المطاف قد ترغب حتى للنظر تاركة Description من التجزئة على أي حال إذا كان من المعقول أن نتوقع أن معظم الكائنات الوقت يمكن تمييزها على أساس لها عنوان وتاريخ النشر (الكتب؟).

هل يمكن أن تنظر حتى تجاهل GUID في وظيفة التجزئة الخاصة بك تماما، واستخدامها فقط في تنفيذ Equals لإزالة الغموض والمحتمل (؟) حالة من الاشتباكات التجزئة.

نصائح أخرى

سهل جدا رمز التجزئة طريقة فئات مخصصة هو أحادي المعامل XOR كل الحقول' تجزئة رموز معا.يمكن أن تكون بسيطة مثل هذه:

int hash = 0;
hash ^= this.Title.GetHashCode();
hash ^= this.PublishDate.GetHashCode();
hash ^= this.Description.GetHashCode();
return hash;

من الرابط أعلاه:

XOR التالية خصائص جميلة:

  • انها لا تعتمد على ترتيب حساب.
  • لا "النفايات" بت.إذا قمت بتغيير حتى بت واحد في واحدة من المكونات القيمة النهائية سوف تتغير.
  • أنها سريعة دورة واحدة على الأكثر بدائية الكمبيوتر.
  • فإنه يحافظ على توزيع موحد.إذا اثنين من القطع التي تجمع بشكل موحد لذلك فإن الجمع يكون.وبعبارة أخرى, أنها لا تميل إلى انهيار مجموعة من هضم في أضيق الفرقة.

XOR لا تعمل بشكل جيد إذا كنت تتوقع أن يكون قيم مكررة في مجالات القيم المكررة سوف يلغي كل منهما الآخر عند Xor.منذ كنت تجزئة معا ثلاثة لا علاقة لها الحقول التي لا ينبغي أن يكون مشكلة في هذه الحالة.

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