سؤال

لست متأكدًا مما يجري بالضبط هنا ، ولكن يبدو أنه في .NET 1.1 ، يمكن أن يدير مندوب حدث غير مؤكد دون مشاكل ، ولكن في .NET 2.0+ يسبب NullReferenceException. أي أفكار لماذا. سيتم تشغيل الكود أدناه بشكل جيد دون مشاكل في 1.1 ، في 2.0 ، يعطي nullreferenceException. أنا فضولي لماذا يتصرف بشكل مختلف؟ ما الذي تغير؟

شكرًا

على سبيل المثال

class Class1
    {
    public delegate void ChartJoinedRowAddedHandler(object sender);



    public static event ChartJoinedRowAddedHandler ChartJoinedRowAdded;
    public static DataTable dt;

    public static void Main()
    {           
        dt = new DataTable();
        dt.RowChanged += new DataRowChangeEventHandler(TableEventHandler);

        object [] obj = new object[]{1,2};
        dt.Columns.Add("Name");
        dt.Columns.Add("Last");
        dt.NewRow();
        dt.Rows.Add(obj);
    }

    private static void TableEventHandler(object sender, DataRowChangeEventArgs e)
    {
        ChartJoinedRowAdded(new object());
    }
}
هل كانت مفيدة؟

المحلول

محدث] AFAIK ، لم يكن هناك أي تغيير هنا في معالجة المندوب الأساسية ؛ الفرق هو في كيفية تصرف البيانات.

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

يوضح تشغيل الكود عبر CSC من 1.1 أن جانب المندوب العام هو نفسه - أعتقد أن الفرق هو أن الرمز القابل للمعتزم الذي يرفع Rochanged كان يبتلع الاستثناء. على سبيل المثال ، اجعل الكود كما هو أدناه:

    Console.WriteLine("Before");
    ChartJoinedRowAdded(new object());
    Console.WriteLine("After");

سترى "قبل" ، ولكن لا "بعد" ؛ تم إلقاء استثناء وابتلاعه من قبل DataTable.

نصائح أخرى

The eventhandler system is basically just a list of functions to call when a given event is raised.

It initializes to the "null" list, and not the empty list, so you need to do

if (ChartJoinedRowAdded != null)
      ChartJoinedRowAdded(new object())

The way events work hasn't really changed from 1.1 to 2

Although the syntax looks like normal aggregation it really isn't:

dt.RowChanged += TableEventHandler;
dt.RowChanged += null;
dt.RowChanged += delegate (object sender, DataRowChangeEventArgs e) {
    //anon
};

Will fire TableEventHandler and then the delegate - the null is just skipped.

You can use null to clear events, but only inside the event firing class:

this.MyEvent = null;

If nothing subscribes your event will be null - see soraz's answer. The DataTable class will contain a similar check and won't fire the event if there are no subscribers.

The standard pattern is:

//events should just about always use this pattern: object, args
public static event EventHandler<MyEventArgs> ChartJoinedRowAdded;


//inheriting classes can override this event behaviour
protected virtual OnChartJoinedRowAdded() {
    if( ChartJoinedRowAdded != null )
        ChartJoinedRowAdded( this, new MyEventArgs(...) );
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top