如果我创建一个lambda回调,例如:
var someInstance = new SomeObject();
someInstance.Finished += (obj, args) =>
{
// Do something
// Deregister here
};
someInstance.DoAction();
如何将回调注销为实际处理程序代码的一部分?这种模式是理想的,因为我可以确保它尽快释放。
我见过类似的问题,但没有直接解决此类示例的问题。
答案 0 :(得分:6)
有类似的东西,
var someInstance = new SomeObject();
EventHandler myDelegate = null;
myDelegate = (obj, args) =>
{
// Do something
// Deregister here
someInstance.Finished -= myDelegate;
};
someInstance.Finished += myDelegate;
someInstance.DoAction();
答案 1 :(得分:5)
如果您想要取消注册,那么最好将您的lambda定义为Action,以便您可以写:
someInstance.Finished += MyCustomAction;
以后
someInstance.Finished -= MyCustomAction;
答案 2 :(得分:5)
您可以在lambda中使用MethodInfo.GetCurrentMethod
来检索lambda的MethodInfo。
使用MethodInfo,您可以使用Delegate.CreateDelegate
来获取代表lambda的正确类型的委托。
使用委托,您可以取消注册lambda,而无需将函数存储在变量中或使其成为命名方法。
class MyClass
{
public event EventHandler TheEvent;
void TestIt()
{
TheEvent += (sender, eventargs) =>
{
Console.WriteLine("Handled!"); // do something in the handler
// get a delegate representing this anonymous function we are in
var fn = (EventHandler)Delegate.CreateDelegate(
typeof(EventHandler), sender,
(MethodInfo)MethodInfo.GetCurrentMethod());
// unregister this lambda when it is run
TheEvent -= fn;
};
// first time around this will output a line to the console
TheEvent(this, EventArgs.Empty);
// second time around there are no handlers attached and it will throw a NullReferenceException
TheEvent(this, EventArgs.Empty);
}
}
答案 3 :(得分:1)
如果您想在之后删除事件处理程序,则应使用命名函数:
someInstance.Finished += HandleFinished;
//...
void HandleFinished(object sender, EventArgs args)
{
someInstance.Finished -= HandleFinished;
}
答案 4 :(得分:1)
这似乎有效:
EventHandler handler = null;
handler = new EventHandler((sender, e) => SomethingHappened -= handler);
SomethingHappened += handler;
请确保您没有将handler
分配给任何其他值,因为闭包与该变量相关联。这就是Resharper抱怨的“获得修改后的关闭”。