سؤال

ولدي C # الطريقة التي يقبل المسند <فو> وإرجاع قائمة من مطابقة البنود ...

public static List<Foo> FindAll( Predicate<Foo> filter )
{
    ...
}

وسوف يكون عامل التصفية في كثير من الأحيان واحد من مجموعة مشتركة ...

public static class FooPredicates
{
    public static readonly Predicate<Foo> IsEligible = ( foo => ...)
    ...
}

... ولكن قد يكون مندوب مجهول.

وأود الآن أن يكون هذا المخبأ طريقة نتائجها في ذاكرة التخزين المؤقت ASP.NET، الدعوات المتكررة حتى مع نفس مندوب فقط إرجاع النتيجة مؤقتا. لهذا، ولست بحاجة لإنشاء مفتاح مخبأ من مندوب. سوف Delegate.GetHashCode () نتائج معقولة لهذا الغرض؟ هناك بعض الأعضاء الأخرى من مندوب أنني يجب أن ننظر؟ هل يمكنك أن تفعل هذا بطريقة أخرى تماما؟

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

المحلول

لأداء مهمة التخزين المؤقت الخاصة بك، يمكنك اتباع الاقتراحات الأخرى وخلق قاموس <المسند <فو>، قائمة <فو >> (ثابتة ل، أو الحقل عضوا العالمي خلاف ذلك) التي تقوم بتخزين النتائج. قبل تنفيذ في الواقع المسند <فو>، وكنت بحاجة لمعرفة ما اذا كان نتيجة موجود بالفعل في القاموس.

ويسمى اسم عام لهذه الوظيفة التخزين المؤقت حتمية التحفيظ - ولها رهيبة:)

ومنذ ذلك الحين C # 3.0 أضاف امدا في وغنيمة المندوبين / العمل وظائفها، مضيفا التحفيظ إلى C # سهلة جدا.

ويس داير لديه أن يجلب المفهوم إلى C # مع بعض أمثلة رائعة.

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

في الرد على استفسارك حول رموز تجزئة مندوب. إذا مندوبين اثنين هي نفسها، d1.GetHashCode () يجب أن يساوي d2.GetHashCode ()، ولكن أنا لست 100٪ حول هذا الموضوع. يمكنك التحقق من ذلك بسرعة عن طريق إعطاء التحفيظ الذهاب، وإضافة للإشارة إلى طريقة FindAll الخاص بك. إذا كان هذا ينتهي عدم صحيح، هناك خيار آخر هو استخدام Linq.Expression <المسند <فو >> كمعلمة. إذا التعابير ليست الإغلاق، ثم التعابير التي تفعل الشيء نفسه ينبغي أن يكون على قدم المساواة.

واسمحوا لي أن أعرف كيف ستسير الامور، وأنا مهتم لمعرفة الجواب عن delegate.Equals.

نصائح أخرى

والمساواة مندوب تبدو في كل استدعاء في قائمة الاحتجاج، واختبار من أجل المساواة في طريقة لطلبه، والهدف من الأسلوب.

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

وإذا كان هذا هو كل ما في الذاكرة، فقط الحفاظ على مندوب نفسها على أنها مفتاح الشباك سيكون على ما يرام - على الرغم من أنه قد يعني أن بعض الكائنات التي عملاء تتوقع أن تكون القمامة التي تم جمعها شنق حولها. إذا كنت بحاجة إلى تسلسل هذا إلى قاعدة بيانات، فإنه يحصل hairier.

ويمكن إجراء طريقة الخاص بقبول مفتاح ذاكرة التخزين المؤقت (على سبيل المثال سلسلة) كذلك؟ (وهذا افتراض في ذاكرة التخزين المؤقت غير كافية.)

والحفاظ على النتائج المخبأة في قاموس <المسند <فو>، قائمة <فو >> هو محرجا بالنسبة لي لأنني أريد ذاكرة التخزين المؤقت ASP.NET للتعامل مع انقضاء بالنسبة لي بدلا من التخزين المؤقت عن النتائج إلى الأبد، لكنه خلاف جيدة المحلول. أعتقد أنني سوف ينتهي الذهاب مع ويل قاموس <المسند <فو>، سلسلة> إلى ذاكرة التخزين المؤقت سلسلة التي يمكن استخدامها في مفتاح مخبأ ASP.NET.

وتشير

وبعض الاختبارات الأولية أن المساواة بين مندوب يفعل "الشيء الصحيح" كما قال آخرون، ولكن Delegate.GetHashCode غير مفيد بشكل مرضي. يكشف العاكس

public override int GetHashCode()
{
    return base.GetType().GetHashCode();
}

لذلك فإن أي المسند <فو> بإرجاع نفس النتيجة.

وبلدي والمسألة المتبقية كيف تعمل المساواة للمندوبين مجهول. ماذا تعني عبارة "نفس طريقة تسمى على نفس الهدف" يعني ذلك؟ ويبدو أنه طالما تم تعريف مندوب في نفس المكان، ما يشير على قدم المساواة. المندوبون مع نفس الهيئة المحددة في أماكن مختلفة ليست كذلك.

static Predicate<int> Test()
{
    Predicate<int> test = delegate(int i) { return false; };
    return test;
}

static void Main()
{
    Predicate<int> test1 = Test();
    Predicate<int> test2 = Test();
    Console.WriteLine(test1.Equals( test2 )); // True

    test1 = delegate(int i) { return false; };
    test2 = delegate(int i) { return false; };
    Console.WriteLine(test1.Equals( test2 )); // False
}

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

وإلا إذا كنت متأكدا تنفيذ مندوب من GetHashCode غير القطعية ولا تسفر عن أي اصطدام وأود أن لا تثق به.

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

وبديل سيكون لخلق طريقة التمديد لالمسند، GetKey ()، يستخدم القاموس الكائن / سلسلة لتخزين واسترجاع كل مفاتيح لجميع يسند. كنت مؤشر إلى القاموس مع مندوب والعودة مفتاحه، وخلق واحد إذا كنت لا تجد ذلك. بهذه الطريقة كنت تتأكدوا من انه يتم الحصول على المفتاح الصحيح لكل مندوب وليس هناك أي تصادم. ومن شأن واحد naiive يكون نوع اسم + الدليل.

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

scroll top