سؤال

لقد حصلت على فئات متعددة ذلك لأسباب معينة ، لا تتبع الرسمية Equals العقد.في الكتابة GetHashCode() هذه الفئات ببساطة العودة 0 بحيث يمكن استخدامها في Hashmap.

بعض من هذه الفئات تنفيذ نفس واجهة وهناك Hashmaps باستخدام هذه الواجهة الرئيسية.لذلك أنا أحسب أن كل فئة يجب على الأقل أن يعود مختلفة (ولكن لا يزال مستمر) قيمة في GetHashCode().

السؤال هو كيفية تحديد هذه القيمة.يجب ببساطة السماح الدرجة الأولى العودة 1, الدرس القادم 2 وهلم جرا ؟ أو أن أحاول شيئا مثل

class SomeClass : SomeInterface {
    public overwrite int GetHashCode() {
        return "SomeClass".GetHashCode();
    }
}

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

تحديث: فإنه ليس من الممكن أن يعود الفرد hashcode لكل كائن ، لأنه يساوي يخالف العقد.Specifially انا تشير إلى هذه المشكلة.

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

المحلول

أنا واجهت هذه المشكلة بالضبط عند كتابة ناقلات الدرجة.أردت أن تقارن نواقل المساواة ، ولكن تعويم العمليات تعطي أخطاء التقريب ، لذلك أردت التقريبية المساواة.قصة قصيرة طويلة ، تجاوز يساوي فكرة سيئة إلا إذا كان التنفيذ هو متماثل, انعكاسية, و متعدية.

الفئات الأخرى سوف نفترض تساوي لديه تلك الخصائص ، و كذلك الطبقات باستخدام تلك الفئات ، حتى تتمكن في نهاية المطاف في غريب الحالات.على سبيل المثال قائمة قد فرض تفرد ولكن في نهاية المطاف مع اثنين من عناصر تقييم قدم بعض العناصر B.

جدول تجزئة هو خير مثال على سلوك غير متوقع عند كسر المساواة.على سبيل المثال:

//Assume a == b, b == c, but a != c
var T = new Dictionary<YourType, int>()
T[a] = 0
T[c] = 1
return T[b] //0 or 1? who knows!

مثال آخر سيكون مجموعة:

//Assume a == b, b == c, but a != c
var T = new HashSet<YourType>()
T.Add(a)
T.Add(c)
if (T.contains(b)) then T.remove(b)
//surely T can't contain b anymore! I sure hope no one breaks the properties of equality!
if (T.contains(b)) then throw new Exception()

أقترح استخدام أسلوب آخر ، مع اسم مثل ApproxEquals.كنت قد تنظر أيضا في تجاوز == مشغل لأنها ليست افتراضية وبالتالي لن يتم استخدامها عن طريق الخطأ من قبل فئات أخرى مثل يساوي يمكن أن يكون.

إذا كنت حقا لا يمكن استخدام إشارة المساواة بين جدول التجزئة لا تفسد أداء الحالات حيث يمكنك.إضافة IApproxEquals واجهة تنفيذ ذلك في صفك ، إضافة طريقة تمديد GetApprox إلى القاموس الذي يعدد مفاتيح تبحث عن فرصة متساوية تقريبا واحدة ، وإرجاع القيمة المقترنة.يمكنك أيضا كتابة قاموس مخصص خاصة 3-الأبعاد ناقلات ، أو كل ما تحتاجه.

نصائح أخرى

إذا كان "ينتهك يساوي العقد" ، ثم أنا لست متأكد من يجب أن يكون استخدامه كمفتاح.

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

باستخدام سلسلة ثابتة لا يساعد كثيرا ستحصل على القيم تقسيم بالتساوي على أنواع ، ولكن هذا عن ذلك...

أنا الغريب ما المنطق سيكون من أجل تجاوز GetHashCode() وإعادة قيمة ثابتة.لماذا تنتهك فكرة تجزئة بدلا من مجرد انتهاك "العقد" و لا تجاوز GetHashCode() تعمل في جميع وترك تطبيق الافتراضي من Object?

تحرير

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

أعتقد أنني لست متأكدا ما كنت تبحث عن...ليس هناك "جيدة" مخطط اختيار المستمر أرقام هذا النموذج.واحد هو أفضل من الآخر.محاولة تحسين الأشياء الخاصة بك حتى أن كنت خلق واقع التجزئة.

عند اصطدام التجزئة تحدث ، HashTable/قاموس المكالمات يساوي إلى العثور على المفتاح الذي تبحث عنه.وذلك باستخدام ثابت رمز التجزئة يزيل السرعة مزايا استخدام تجزئة في المقام الأول - يصبح البحث الخطي.

أنت تقول أن يساوي الأسلوب لم يتم تنفيذها وفقا للعقد.ماذا تقصد بالضبط مع هذا ؟ اعتمادا على نوع من الانتهاك ، HashTable أو القاموس سوف تكون مجرد بطيئة (البحث الخطي) أو لا تعمل على الإطلاق.

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