问题描述
我有一个处理来自 WinForms 控件的事件的类.根据用户正在做什么,我推迟了类的一个实例并创建一个新实例来处理相同的事件.我需要先从事件中取消订阅旧实例 - 很容易.如果可能,我想以非专有的方式执行此操作,这似乎是 IDisposable 的工作.但是,大多数文档仅在使用非托管资源时才推荐 IDisposable,这在此处不适用.
I have a class that handles events from a WinForms control. Based on what the user is doing, I am deferencing one instance of the class and creating a new one to handle the same event. I need to unsubscribe the old instance from the event first - easy enough. I'd like to do this in a non-proprietary manner if possible, and it seems like this is a job for IDisposable. However, most documentation recommends IDisposable only when using unmanaged resources, which does not apply here.
如果我在 Dispose() 中实现 IDisposable 并取消订阅事件,我是否违背了它的意图?我应该提供一个 Unsubscribe() 函数并调用它吗?
If I implement IDisposable and unsubscribe from the event in Dispose(), am I perverting its intention? Should I instead provide an Unsubscribe() function and call that?
这里有一些虚拟代码,显示了我在做什么(使用 IDisposable).我的实际实现与一些专有数据绑定(长话短说)有关.
Here's some dummy code that kind of shows what I'm doing (using IDisposable). My actual implementation is related to some proprietary data binding (long story).
class EventListener : IDisposable
{
private TextBox m_textBox;
public EventListener(TextBox textBox)
{
m_textBox = textBox;
textBox.TextChanged += new EventHandler(textBox_TextChanged);
}
void textBox_TextChanged(object sender, EventArgs e)
{
// do something
}
public void Dispose()
{
m_textBox.TextChanged -= new EventHandler(textBox_TextChanged);
}
}
class MyClass
{
EventListener m_eventListener = null;
TextBox m_textBox = new TextBox();
void SetEventListener()
{
if (m_eventListener != null) m_eventListener.Dispose();
m_eventListener = new EventListener(m_textBox);
}
}
在实际代码中,EventListener"类涉及的比较多,每个实例都有唯一的意义.我在一个集合中使用这些,并在用户点击时创建/销毁它们.
In the actual code, the "EventListener" class is more involved, and each instance is uniquely significant. I use these in a collection, and create/destroy them as the user clicks around.
结论
我接受 gbjbaanb 的回答,至少目前是这样.我觉得使用熟悉的界面的好处超过了在不涉及非托管代码的情况下使用它的任何可能的缺点(这个对象的用户怎么会知道?).
I'm accepting gbjbaanb's answer, at least for now. I feel that the benefit of using a familiar interface outweighs any possible downside of using it where no unmanaged code is involved (how would a user of this object even know that?).
如果有人不同意 - 请发表/评论/编辑.如果可以对 IDisposable 提出更好的论据,那么我将更改已接受的答案.
If anyone disagrees - please post/comment/edit. If a better argument can be made against IDisposable, then I'll change the accepted answer.
推荐答案
是的,去吧.尽管有些人认为 IDisposable 仅适用于非托管资源,但事实并非如此——非托管资源恰好是最大的胜利,也是实现它的最明显原因.我认为它获得了这个想法是因为人们想不出任何其他理由来使用它.它不像是一个性能问题的终结器,而且 GC 处理起来并不容易.
Yes, go for it. Although some people think IDisposable is implemented only for unmanaged resources, this is not the case - unmanaged resources just happens to be the biggest win, and most obvious reason to implement it. I think its acquired this idea because people couldn't think of any other reason to use it. Its not like a finaliser which is a performance problem and not easy for the GC to handle well.
将任何整理代码放入您的处置方法中.与试图记住取消引用相比,它会更清晰、更清晰,并且更有可能防止内存泄漏,并且更易于正确使用.
Put any tidy-up code in your dispose method. It'll be clearer, cleaner and significantly more likely to prevent memory leaks and a damn sight easier to use correctly than trying to remember to un-do your references.
IDisposable 的目的是让您的代码更好地工作,而无需您进行大量手动工作.善用它的力量,克服一些人为的设计意图"胡说八道.
The intention of IDisposable is to make your code work better without you having to do lots of manual work. Use its power in your favour and get over some artificial "design intention" nonsense.
我记得当 .NET 首次出现时,很难说服 Microsoft 确定性最终确定的有用性 - 我们赢得了战斗并说服他们添加它(即使它当时只是一种设计模式),使用它!
I remember it was difficult enough to persuade Microsoft of the usefulness of deterministic finalisation back when .NET first came out - we won the battle and persuaded them to add it (even if it was only a design pattern at the time), use it!
这篇关于使用 IDisposable 取消订阅事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!