相关疑难解决方法(0)

是否滥用IDisposable和"使用"作为获取异常安全的"范围行为"的手段?

我经常在C++中使用的东西是让一个类通过构造函数和析构函数A处理另一个类的状态入口和退出条件,以确保如果该范围内的某些东西抛出异常,那么B将具有已知状态范围已退出.就首字母缩略词而言,这不是纯粹的RAII,但它仍然是一种既定的模式.BA

在C#中,我经常想做

class FrobbleManager
{
    ...

    private void FiddleTheFrobble()
    {
        this.Frobble.Unlock();
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
        this.Frobble.Lock();
    }
}
Run Code Online (Sandbox Code Playgroud)

这需要像这样做

private void FiddleTheFrobble()
{
    this.Frobble.Unlock();

    try
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw
        Bar();                  // Can throw
    }
    finally
    {
        this.Frobble.Lock();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想保证退货Frobble时的状态FiddleTheFrobble.代码会更好

private void FiddleTheFrobble()
{
    using (var janitor = new FrobbleJanitor(this.Frobble))
    {            
        Foo();                  // Can throw
        this.Frobble.Fiddle();  // Can throw …
Run Code Online (Sandbox Code Playgroud)

c# exception-handling raii

107
推荐指数
6
解决办法
6151
查看次数

使用IDisposable取消订阅事件

我有一个类来处理来自WinForms控件的事件.根据用户正在做的事情,我正在引用该类的一个实例并创建一个新实例来处理同一事件.我需要先从事件中取消订阅旧实例 - 这很容易.如果可能的话,我想以非专有方式这样做,看起来这是IDisposable的工作.但是,大多数文档仅在使用非托管资源时才建议使用IDisposable,这在此处不适用.

如果我实现IDisposable并取消订阅Dispose()中的事件,我是否会歪曲它的意图?我应该提供一个Unsubscribe()函数并调用它吗?


编辑:这是一些虚拟代码,它显示了我正在做的事情(使用IDisposable).我的实际实现与一些专有数据绑定(长篇故事)有关.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

在实际代码中,"EventListener"类涉及更多,每个实例都具有独特的重要性.我在集合中使用它们,并在用户点击时创建/销毁它们.


结论

我接受gbjbaanb的回答,至少目前如此.我觉得使用熟悉的界面的好处超过了在没有涉及非托管代码的情况下使用它的任何可能的缺点(这个对象的用户怎么会知道?).

如果有人不同意 - 请发帖/评论/编辑.如果可以对IDisposable做出更好的论证,那么我将改变接受的答案.

.net events idisposable unsubscribe

49
推荐指数
5
解决办法
2万
查看次数

调用Dispose()vs对象超出范围/方法完成

我有一个方法,里面有一个try/catch/finaly块.在try块中,我声明SqlDataReader如下:

SqlDataReader aReader = null;          
aReader = aCommand.ExecuteReader();
Run Code Online (Sandbox Code Playgroud)

finally块中,手动处理的对象是在类级别设置的对象.因此,在该方法的对象,其实现IDisposable,如SqlDataReader上述,他们得到自动处理的?Close()aReader执行while循环后调用,以获取阅读器的内容(应该是Dispose()调用的内容Close()).如果没有调用Close(),当方法完成或对象超出范围时,是否会自动关闭/处置此对象?

编辑:我知道这个using声明,但有些情况令我感到困惑.

c# idisposable using using-statement

14
推荐指数
2
解决办法
1万
查看次数