إذا قمت بالتسجيل لحدث في C# أثناء الإرسال، فهل أضمن عدم الاتصال بي مرة أخرى أثناء الإرسال؟

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

  •  02-07-2019
  •  | 
  •  

سؤال

في C#، أجد نفسي أحيانًا أرغب في تسجيل طريقة لحدث ما في منتصف إرسال نفس الحدث.على سبيل المثال، إذا كان لدي فصل دراسي يقوم بنقل الحالات بناءً على عمليات الإرسال المتعاقبة لنفس الحدث، فقد أرغب في أن يقوم معالج الحالة الأولى بإلغاء تسجيل نفسه وتسجيل المعالج الثاني.ومع ذلك، لا أريد إرسال المعالج الثاني حتى يتم تشغيل الحدث في المرة التالية.

والخبر السار هو أنه يبدو أن تطبيق Microsoft لـ C# يتصرف بهذه الطريقة تمامًا.يتم استبدال سكر بناء جملة تسجيل الحدث باستدعاء System.Delegate.Combine، الذي يقوم فقط بربط قائمة الاستدعاء الحالية والطريقة الجديدة في قائمة منفصلة وتعيينها إلى خاصية الحدث.هذا يعطيني بالضبط السلوك الذي أريده.

إذن سؤالي هو:هل هذا السلوك مضمون بمعايير اللغة؟أحب أن أكون قادرًا على تشغيل كود C# الخاص بي على منصات أخرى ضمن نظام mono وأريد عمومًا التأكد من أنني لا أقوم بافتراضات حول معيار اللغة بناءً على تنفيذه.

لم أتمكن من العثور على أي معلومات محددة عن MSDN.

إذا كنت تريد مثالاً محددًا لما أتحدث عنه، فإليك مثالًا:

    delegate void TestDelegate();
    static event TestDelegate TestEvent;

    static void Main (string[] args) {
        TestEvent += TestDelegateInstanceFirst;
        TestEvent();
        TestEvent();
    }

    static void TestDelegateInstanceFirst () {
        Console.WriteLine("First");
        TestEvent += TestDelegateInstanceSecond;
    }

    static void TestDelegateInstanceSecond () {
        Console.WriteLine("Second");
    }

على الأقل في نظام التشغيل Windows، يكون الإخراج:

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

المحلول

نعم، إنه مضمون.

من مواصفات C# 3.0 الموحدة، القسم 15.1:

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

لاحظ "قائمة الاستدعاءات الجديدة".ومرة أخرى في القسم 15.3:

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

أخيرًا، ينص MSDN لـ System.Delegate على ما يلي:

المندوبون غير قابلين للتغيير.بمجرد إنشائها ، لا تتغير قائمة الاحتجاج من المندوب.

أظن أن هناك شيئًا ما في مواصفات CLI - سأتحقق مما إذا كنت ترغب في ذلك، ولكن آمل أن يكون هؤلاء الثلاثة قد أعطوك الثقة الكافية :)

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