取消订阅委托与函数中的事件
Unsubscribing from the event in delegate vs function
为什么 C# 允许在事件处理程序定义为函数时取消订阅事件,但在事件处理程序定义为委托时不允许取消订阅?
考虑以下有效的代码:
void SomeFunction()
{
var eventRaiser = ClassRaisingEvent.GetEventRaiser();
void handler(object sender, EventArgs ev)
{
ProcessData(ev);
eventRaiser.OnEvent -= handler;
}
eventRaiser.OnEvent += handler
eventRaiser.Process();
}
但是无法在指定位置编译:
void SomeFunction()
{
var eventRaiser = ClassRaisingEvent.GetEventRaiser();
DelegateType handler = (object sender, EventArgs ev) =>
{
ProcessData(ev);
eventRaiser.OnEvent -= handler; // FAILS here with "Use of unassigned local variable 'handler '"
}
eventRaiser.OnEvent += handler
eventRaiser.Process();
}
编辑:这个问题不是如何退订。这就是为什么(在技术意义上)函数名称在函数的范围内被捕获,但委托的不是。
EDIT2:回答 (尤其是回答中的第 2 部分)解释了我所看到的行为。
本地函数是在编译时定义的,就像其他函数一样。但是,handler
变量仅在运行时已知。因此,正如编译器告诉您的那样,您不能在 handler
变量被赋值之前使用它,这意味着在您的委托结束 }
之后。
要使第二个代码段正常工作,您可以先初始化变量:
void SomeFunction()
{
var eventRaiser = ClassRaisingEvent.GetEventRaiser();
DelegateType handler = null;
handler = (object sender, EventArgs ev) =>
{
ProcessData(ev);
eventRaiser.OnEvent -= handler;
};
eventRaiser.OnEvent += handler;
eventRaiser.Process();
}
为什么 C# 允许在事件处理程序定义为函数时取消订阅事件,但在事件处理程序定义为委托时不允许取消订阅?
考虑以下有效的代码:
void SomeFunction()
{
var eventRaiser = ClassRaisingEvent.GetEventRaiser();
void handler(object sender, EventArgs ev)
{
ProcessData(ev);
eventRaiser.OnEvent -= handler;
}
eventRaiser.OnEvent += handler
eventRaiser.Process();
}
但是无法在指定位置编译:
void SomeFunction()
{
var eventRaiser = ClassRaisingEvent.GetEventRaiser();
DelegateType handler = (object sender, EventArgs ev) =>
{
ProcessData(ev);
eventRaiser.OnEvent -= handler; // FAILS here with "Use of unassigned local variable 'handler '"
}
eventRaiser.OnEvent += handler
eventRaiser.Process();
}
编辑:这个问题不是如何退订。这就是为什么(在技术意义上)函数名称在函数的范围内被捕获,但委托的不是。
EDIT2:回答
本地函数是在编译时定义的,就像其他函数一样。但是,handler
变量仅在运行时已知。因此,正如编译器告诉您的那样,您不能在 handler
变量被赋值之前使用它,这意味着在您的委托结束 }
之后。
要使第二个代码段正常工作,您可以先初始化变量:
void SomeFunction()
{
var eventRaiser = ClassRaisingEvent.GetEventRaiser();
DelegateType handler = null;
handler = (object sender, EventArgs ev) =>
{
ProcessData(ev);
eventRaiser.OnEvent -= handler;
};
eventRaiser.OnEvent += handler;
eventRaiser.Process();
}