إن الأحداث التي يتم تنفيذها المندوبين .صافي ما نقطة .الحدث IL القسم ؟

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

سؤال

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

الجواب على السؤال أعلاه يجعل هذه النقطة:

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

MSDN المادة مرتبطة من نفس السؤال ("مجال مثل الأحداث") ويضيف:

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

الرغبة في دراسة أخرى, لقد بنيت اختبار المشروع من أجل عرض IL هذا الحدث و مندوب يتم تجميعها إلى:

public class TestClass
{
    public EventHandler handler;
    public event EventHandler FooEvent;

    public TestClass()
    { }
}

كنت أتوقع مندوب المجال handler و الحدث FooEvent ترجمة إلى تقريبا نفس رمز IL, مع بعض طرق إضافية إلى التفاف الوصول إلى مترجم ولدت FooEvent الحقل.ولكن IL ولدت لم يكن تماما ما كنت أتوقع:

.class public auto ansi beforefieldinit TestClass
    extends [mscorlib]System.Object
{
    .event [mscorlib]System.EventHandler FooEvent
    {
        .addon instance void TestClass::add_FooEvent(class [mscorlib]System.EventHandler)
        .removeon instance void TestClass::remove_FooEvent(class [mscorlib]System.EventHandler)
    }

    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        // Constructor IL hidden
    }

    .field private class [mscorlib]System.EventHandler FooEvent
    .field public class [mscorlib]System.EventHandler handler
}

منذ الأحداث ليست أكثر من المندوبين مترجم ولدت add و remove أساليب, لم أكن أتوقع أن أرى الأحداث يعامل أي شيء أكثر من ذلك في إلينوي.ولكن إضافة وإزالة أساليب محددة في المقطع الذي يبدأ .event, لا .method كالمعتاد الأساليب.

بلدي في نهاية المطاف الأسئلة هي:إن الأحداث تنفذ ببساطة كما المندوبين accessor الطرق ، ما هو الهدف من وجود .event IL القسم ؟ لا يمكن أن تنفذ في IL دون هذا باستخدام .method أقسام ؟ هو .event أي ما يعادل .method?

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

المحلول

أنا لست متأكدا من أن يثير الدهشة...مقارنة مع نفس خصائص vs المجالات (منذ الخصائص قبل نفس الوظيفة الأحداث:التغليف عن طريق accessors):

.field public string Foo // public field
.property instance string Bar // public property
{
    .get instance string MyType::get_Bar()
    .set instance void MyType::set_Bar(string)
}

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

الشائعة الأخرى تطبيقات:

متفرق-الأحداث (الضوابط ، الخ) - EventHandlerList (أو مشابهة):

// only one instance field no matter how many events;
// very useful if we expect most events to be unsubscribed
private EventHandlerList events = new EventHandlerList();
protected EventHandlerList Events {
    get { return events; } // usually lazy
}

// this code repeated per event
private static readonly object FooEvent = new object();
public event EventHandler Foo
{
    add { Events.AddHandler(FooEvent, value); }
    remove { Events.RemoveHandler(FooEvent, value); }
}
protected virtual void OnFoo()
{
    EventHandler handler = Events[FooEvent] as EventHandler;
    if (handler != null) handler(this, EventArgs.Empty);
}

(سبق هو إلى حد كبير الفقري الفوز أشكال الأحداث)

الواجهة (على الرغم من أن هذا يخلط بين "المرسل" قليلا ؛ بعض الوسيط رمز في كثير من الأحيان مفيدة):

private Bar wrappedObject; // via ctor
public event EventHandler SomeEvent
{
    add { wrappedObject.SomeOtherEvent += value; }
    remove { wrappedObject.SomeOtherEvent -= value; }
}

(المذكورة أعلاه يمكن أيضا أن تستخدم على نحو فعال تسمية الحدث)

نصائح أخرى

الأحداث ليست نفس المندوبين.الأحداث لتغليف إضافة/إزالة معالج الحدث.معالج يمثل مع مندوب.

لك يمكن أن مجرد كتابة AddClickHandler/RemoveClickHandler الخ على كل حال - ولكن كان يمكن أن تكون مؤلمة نسبيا ، لن تجعل من السهل على أدوات مثل VS فصل الأحداث من أي شيء آخر.

هذا هو مجرد مثل خصائص حقا - هل يمكن كتابة GetSize/SetSize الخ (كما كنت تفعل في جاوة) ولكن عن طريق فصل خصائص ، هناك النحوية الاختصارات المتاحة وأفضل أداة الدعم.

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

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

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

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