Hax*_*lit 54 c# events anonymous-methods
我想知道这是否真的有效?
private void RegisterKeyChanged(T item)
{
item.OnKeyChanged += (o, k) => ChangeItemKey((T)o, k);
}
private void UnRegisterKeyChanged(T item)
{
item.OnKeyChanged -= (o, k) => ChangeItemKey((T)o, k);
}
Run Code Online (Sandbox Code Playgroud)
编译器如何知道事件处理程序是否相同?这甚至是推荐的吗?
Rya*_*ndy 60
有一个MSDN页面讨论这个:
特别注意:
如果您以后不必取消订阅[sic]事件,则可以使用添加赋值运算符(+ =)将匿名方法附加到事件中.
并且:
重要的是要注意,如果您使用匿名函数订阅它,则无法轻松取消订阅事件.要在此方案中取消订阅,必须返回订阅事件的代码,将匿名方法存储在委托变量中,然后将委托添加到事件中.通常,如果您必须在代码中的某个稍后时间点取消订阅该事件,我们建议您不要使用匿名函数来订阅事件.
sb.*_*son 14
对于任何感兴趣的人,您可以添加和删除这样的匿名事件处理程序
public class Musician
{
public void TuneGuitar()
{
Metronome metronome = new Metronome();
EventHandler<EventArgs> handler = null;
handler = (sender, args) =>
{
// Tune guitar
// ...
// Unsubscribe from tick event when guitar sound is perfect
metronome.Tick -= handler;
};
// Attach event handler
metronome.Tick += handler;
}
}
public class Metronome
{
event EventHandler<EventArgs> Tick;
}
Run Code Online (Sandbox Code Playgroud)
更新:在C#7.0中,我们支持本地函数,因此该TuneGuitar
方法现在可以编写为:
public void TuneGuitar()
{
Metronome metronome = new Metronome();
void handler(object sender, EventArgs args)
{
// Tune guitar
// ...
// Unsubscribe from tick event when guitar sound is perfect
metronome.Tick -= handler;
};
// Attach event handler
metronome.Tick += handler;
}
Run Code Online (Sandbox Code Playgroud)
如果您需要取消订阅事件处理程序,则需要明确引用具体的委托.看着Delegate.Equality
你会发现代表不只是使用引用相等进行比较,但这对于匿名委托并不重要.
对于匿名委托,编译器(基本上)只是为每个匿名委托创建一个新的"非匿名"委托,即使委托主体是相同的.因此,当您使用您提供的代码示例时,框架将找不到取消订阅的委托.
归档时间: |
|
查看次数: |
38027 次 |
最近记录: |