提问人:stevebblee 提问时间:10/8/2008 最后编辑:Uwe Keimstevebblee 更新时间:6/21/2016 访问量:1190
事件处理程序行为差异 .net 1.1 与 2.0 与 null 委托
Event Handler behavioral difference .net 1.1 vs 2.0 with null delegate
问:
不知道这里到底发生了什么,但似乎在 .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());
}
}
答:
1赞
Marc Gravell
10/8/2008
#1
[更新]AFAIK,这里对基本代表处理没有变化;区别在于 DataTable 的行为方式。
然而!使用静态事件时要非常小心,尤其是在订阅实例(而不是静态方法)时。这是保持大量物体处于活动状态而不被垃圾回收的好方法。
从 1.1 通过 csc 运行代码表明通用委托端是相同的 - 我认为区别在于引发 RowChanged 的 DataTable 代码正在吞噬异常。例如,编写如下代码:
Console.WriteLine("Before");
ChartJoinedRowAdded(new object());
Console.WriteLine("After");
您会看到“之前”,但不会看到“之后”;DataTable 抛出并吞没了异常。
1赞
Soraz
10/8/2008
#2
事件处理程序系统基本上只是一个函数列表,在引发给定事件时要调用。
它初始化为“null”列表,而不是空列表,因此您需要这样做
if (ChartJoinedRowAdded != null)
ChartJoinedRowAdded(new object())
0赞
Keith
10/8/2008
#3
从 1.1 到 2,事件的工作方式并没有真正改变
虽然语法看起来像普通的聚合,但实际上并非如此:
dt.RowChanged += TableEventHandler;
dt.RowChanged += null;
dt.RowChanged += delegate (object sender, DataRowChangeEventArgs e) {
//anon
};
将触发,然后是委托 - null 被跳过。TableEventHandler
可以使用 null 清除事件,但只能在事件触发类中清除:
this.MyEvent = null;
如果没有订阅,您的事件将为 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(...) );
}
评论