Eri*_*ric 214 c# delegates anonymous-methods
是否可以从事件中取消订阅匿名方法?
如果我订阅这样的事件:
void MyMethod()
{
Console.WriteLine("I did it!");
}
MyEvent += MyMethod;
Run Code Online (Sandbox Code Playgroud)
我可以这样取消订阅:
MyEvent -= MyMethod;
Run Code Online (Sandbox Code Playgroud)
但是如果我使用匿名方法订阅:
MyEvent += delegate(){Console.WriteLine("I did it!");};
Run Code Online (Sandbox Code Playgroud)
是否有可能取消订阅这种匿名方法?如果是这样,怎么样?
Jac*_*all 221
Action myDelegate = delegate(){Console.WriteLine("I did it!");};
MyEvent += myDelegate;
// .... later
MyEvent -= myDelegate;
Run Code Online (Sandbox Code Playgroud)
只需保持对代表的引用.
J c*_*J c 139
一种技术是声明一个变量来保存匿名方法,该方法随后可以在匿名方法本身中使用.这对我有用,因为在处理事件后所需的行为是取消订阅.
例:
MyEventHandler foo = null;
foo = delegate(object s, MyEventArgs ev)
{
Console.WriteLine("I did it!");
MyEvent -= foo;
};
MyEvent += foo;
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 21
从内存中,当涉及使用匿名方法创建的委托的等效性时,规范明确地不保证行为.
如果您需要取消订阅,您应该使用"普通"方法或将代理保留在其他位置,以便您可以取消订阅您用于订阅的完全相同的委托.
小智 16
在3.0中可以缩短为:
MyHandler myDelegate = ()=>Console.WriteLine("I did it!");
MyEvent += myDelegate;
...
MyEvent -= myDelegate;
Run Code Online (Sandbox Code Playgroud)
maz*_*nko 10
由于C#7.0的本地功能功能已经发布,该办法建议通过Ĵç变得很整洁。
void foo(object s, MyEventArgs ev)
{
Console.WriteLine("I did it!");
MyEvent -= foo;
};
MyEvent += foo;
Run Code Online (Sandbox Code Playgroud)
因此,说实话,您这里没有匿名函数作为变量。但是我想在您的情况下使用它的动机可以应用于局部函数。
您可以检测您的类,而不是保留对任何委托的引用,以便将事件的调用列表返回给调用者.基本上你可以写这样的东西(假设MyEvent在MyClass中声明):
public class MyClass
{
public event EventHandler MyEvent;
public IEnumerable<EventHandler> GetMyEventHandlers()
{
return from d in MyEvent.GetInvocationList()
select (EventHandler)d;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,您可以从MyClass外部访问整个调用列表,并取消订阅您想要的任何处理程序.例如:
myClass.MyEvent -= myClass.GetMyEventHandlers().Last();
Run Code Online (Sandbox Code Playgroud)
我写了一个完整的帖子关于这个tecnique 这里.
一种蹩脚的方法:
public class SomeClass
{
private readonly IList<Action> _eventList = new List<Action>();
...
public event Action OnDoSomething
{
add {
_eventList.Add(value);
}
remove {
_eventList.Remove(value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这可能不起作用或者是最有效的方法,但应该完成工作.
| 归档时间: |
|
| 查看次数: |
66934 次 |
| 最近记录: |