يتم استدعاء طريقة ملحق على مرجع "فارغ" (أي.حدث بدون مشتركين) شر؟

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

  •  05-07-2019
  •  | 
  •  

سؤال

شر أم لا شر؟

public static void Raise(this EventHandler handler, object sender, EventArgs args)
{
   if (handler != null)
   {
      handler(sender, args);
   }
}

// Usage:
MyButtonClicked.Raise(this, EventArgs.Empty);

// This works too! Evil?
EventHandler handler = null;
handler.Raise(this, EVentArgs.Empty);

لاحظ أنه نظرًا لطبيعة طرق الامتداد، لن يقوم MyButtonClicked.Raise بطرح NullReferenceException إذا كانت قيمة MyButtonClicked فارغة.(على سبيل المثال.لا يوجد مستمعون لحدث MyButtonClicked).

شر أم لا؟

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

المحلول

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

نصائح أخرى

ويمكنك دائما يعلن الأحداث الخاصة بك مثل هذا (وليس أن أنا أوصى به):

public event EventHandler<EventArgs> OnClicked = delegate { };

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

وربما يمكنك التخلص من الكلمة مندوب في C # 3.0 ...

لا تنس أن تستخدم [MethodImpl(MethodImplOptions.NoInlining)]، وإلا من الممكن أنه لا ترابط آمن.

و(اقرأ هذا قبل في مكان ما لفترة طويلة، تذكرت ذلك، غوغليد وجدت HTTP: //blog.quantumbitdesigns. كوم / العلامة / الأحداث / )

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

للي هذا يبدو واحدة من gottchas C # الصورة التي تسبب الخلل عند الناس لا يعلمون / تنسى للتحقق من باطل في كل مرة.

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

وكنت أيضا إضافة هاتين الطريقتين إلى الفئة:

    public static void Raise(this EventHandler handler, object sender)
    {
        Raise(handler, sender, EventArgs.Empty);
    }

    public static void Raise<TA>(this EventHandler<TA> handler, object sender, TA args)
        where TA : EventArgs
    {
        if (handler != null)
        {
            handler(sender, args);
        }
    }

لماذا سيكون الشر؟

والغرض منه واضح:فإنه يثير الحدث MyButtonClicked.

إنه يضيف حملًا إضافيًا لاستدعاء دالة، ولكن في .NET إما سيتم تحسينه بعيدًا أو سريعًا جدًا على أي حال.

إنه أمر تافه بعض الشيء، لكنه يعمل على إصلاح شكواي الأكبر مع C#.

على العموم، أعتقد أنها فكرة رائعة، ومن المحتمل أن تسرقها.

ولن أقول انها الشر، ولكن أنا مهتم في كيفية طريقة الملحق الخاص بك تناسبها مع

protected virtual OnSomeEvent(EventArgs e){ }

ونمط وكيف يتعامل مع التمدد عبر الميراث. هل نفترض أن كل الفئات الفرعية بمعالجة الحدث بدلا من تجاوز طريقة؟

وعلى الرغم من أنني لن describ أنها <م> الشر ، فإنه لا يزال لديه تداعيات سلبية، كما أنه يضيف الحمل غير الضرورية:

عند داعيا

وmyEvent.Raise(this, new EventArgs());

وتهيئة EventArgs الكائن في جميع الحالات، حتى لو كان لا أحد اشتركت في myEvent.

عند استخدام

if (myEvent!= null) {
   myEvent(this, new EventArgs());
}
تتم تهيئة

وEventArgs فقط إذا كان شخص مشترك في myEvent.

ورمي استثناء عندما لا تكون هناك معالجات ليست في الحقيقة من الأفضل قبل أكثر من غيرها. إذا لم يكن لديك معالجات أنه من الأفضل أن تكون فارغة بدلا من فارغة.

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