是否可以从事件中取消订阅匿名方法?
如果我订阅这样的事件:
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)
是否有可能取消订阅这种匿名方法?如果是这样,怎么样?
好吧,所以这更像是一个答案而不是一个问题,但在提出这个问题之后,将Dustin Campbell,Egor的各个部分以及" IObservable/Rx/Reactive框架 "中的最后一个提示拉到一起,我想我为这个特殊问题制定了可行的解决方案.它可能会被IObservable/Rx/Reactive框架完全取代,但只有经验才会显示出来.
我故意创造了一个新问题,给我空间来解释我如何得到这个解决方案,因为它可能不会立即显而易见.
有很多相关的问题,大多数人告诉你,如果你想以后能够分离它们,你就不能使用内联lambda:
确实,如果您希望以后能够分离它们,您需要保留对lambda的引用.但是,如果您只是希望事件处理程序在订阅者超出范围时自行分离,则此答案适合您.
何时实施IDisposable的最佳做法是什么?
如果在类中有一个托管对象,那么实现它是最好的经验法则,还是依赖于对象是在类中创建还是只是传入?我是否也应该为没有托管对象的类做到这一点?
如果对象A侦听来自对象B的事件,则对象B将使对象A保持活动状态.是否存在可以阻止这种情况的弱事件的标准实现?我知道WPF有一些机制,但我正在寻找与WPF无关的东西.我猜测解决方案应该在某处使用弱引用.
我希望用匿名委托和lambda表达式清除一些东西,用于为C#中的事件处理程序创建一个方法,至少对我自己来说.
假设我们有一个事件添加一个匿名委托或一个lambda表达式(对于那些可以使用较新版本.NET的幸运人群).
SomeClass.SomeEvent += delegate(object o, EventArg e) { /* do something */ };
Run Code Online (Sandbox Code Playgroud)
我已经读过,过去的人们已经忘记了仍然有处理程序的事件,这些处理程序会阻止类被垃圾收集.如何在不在类中将SomeEvent设置为null的情况下删除添加的处理程序.以下不是一个全新的处理程序吗?
SomeClass.SomeEvent -= delegate(object o, EventArg e) { /* do something */ };
Run Code Online (Sandbox Code Playgroud)
我可以看到将匿名委托或lambda表达式存储在变量中.但至少对我而言,这似乎打败了能够简单而简洁地添加事件处理程序的全部目的.
SomeEventDelegate handler = new SomeEventDelegate(delegate(object o, EventArg e) { /* do something */ });
SomeClass.SomeEvent += handler;
// ... stuff
SomeClass.SomeEvent -= handler;
Run Code Online (Sandbox Code Playgroud)
我再次理解你可以......
public override Dispose(bool disposing)
{
_someEvent = null;
this.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
但是我只是从事件中删除动态创建的方法更有趣.希望有人可以为我揭开这一点.谢谢!
由于C#使用垃圾收集.什么时候需要使用.Dispose释放内存?
我意识到有一些情况所以我会尝试列出我能想到的.
假设您有一个包含事件属性的类.如果在本地上下文中实例化此类,而没有外部引用,则会为事件分配lambda表达式以防止实例被垃圾回收?
{
var o = new MyClass();
o.MyClassEvent += (args) => {};
}
// Will 'o' be eligible for garbage collection here?
Run Code Online (Sandbox Code Playgroud) 在ClassA中,我有一个计时器对象.在这个类中,我为timer elapsed事件注册了事件处理程序.在另一个类ClassB中,我有一个用于timer elapsed事件的公共事件处理程序.所以我在ClassA中从ClassB注册事件处理程序,如下所示:
myTimer.Elapsed += ClassBInstance.TimerElapsed
Run Code Online (Sandbox Code Playgroud)
如果我要创建一个新的ClassBInstance实例,并且当ClassB的事件处理程序的前一个实例仍然与计时器的Elapsed事件绑定时,会触发计时器已过时事件会发生什么?
例如:
ClassB classBInstance = new ClassB();
myTimer.Elapsed += classBInstance.TimerElapsed
classBInstance = new ClassB();
myTimer.Elapsed += classBInstance.TimerElapsed
Run Code Online (Sandbox Code Playgroud) 如果我创建一个.NET类,用这样的匿名函数订阅一个事件:
void MyMethod()
{
Application.Current.Deactivated += (s,e) => { ChangeAppearance(); };
}
Run Code Online (Sandbox Code Playgroud)
这个事件处理程序是否会使我的类不被垃圾收集?
如果没有,喔!但如果是这样,你能告诉我删除语法吗?只使用 - =使用相同的代码似乎是错误的.