1

不确定这里到底发生了什么,但似乎在 .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());
    }
}
4

3 回答 3

1

[更新] AFAIK,这里的基本委托处理没有变化;区别在于 DataTable 的行为方式。

然而!使用静态事件要非常小心,特别是如果您订阅的是实例(而不是静态方法)。这是保持大量对象存活而不被垃圾收集的好方法。

从 1.1 通过 csc 运行代码表明一般委托方是相同的 - 我认为不同之处在于引发 RowChanged 的​​ DataTable 代码正在吞噬异常。例如,使代码如下所示:

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

你会看到“之前”,但没有“之后”;DataTable 引发并吞下异常。

于 2008-10-08T08:11:33.247 回答
1

事件处理程序系统基本上只是在引发给定事件时要调用的函数列表。

它初始化为“空”列表,而不是空列表,所以你需要做

if (ChartJoinedRowAdded != null)
      ChartJoinedRowAdded(new object())
于 2008-10-08T08:29:41.323 回答
0

从 1.1 到 2,事件的工作方式并没有真正改变

尽管语法看起来像普通聚合,但实际上并非如此:

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

将触发TableEventHandler然后委托 - 只是跳过空值。

您可以使用 null 清除事件,但只能在事件触发类中:

this.MyEvent = null;

如果没有人订阅,您的活动将为空 - 请参阅 soraz 的回答。该类DataTable将包含类似的检查,如果没有订阅者,则不会触发该事件。

标准模式是:

//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(...) );
}
于 2008-10-08T09:55:13.583 回答