通过引用传递IDisposable对象会导致错误?

dan*_*die 2 c# dispose idisposable pass-by-reference

我正在尝试创建一个处理实现IDisposable的对象的通用方法,称为DisposeObject()

为了确保我处理原始引用指向的对象,我试图通过引用传递一个对象.

但是我收到了一个编译错误

'ref'参数类型与参数类型不匹配

在下面的(简化的)码,这两个_Baz_Bar实施IDisposable的.

替代文字

所以问题是,

  1. 为什么我收到此错误?
  2. 有办法解决它吗?

[更新] 从目前为止提供的答案,只要我没有将IDisposable参数设置为null,我可以简单地通过值传递一个对象而不使用ref.我现在还有另一个麻烦,无论是否nullDisposeObject方法中设置一次性对象.

以下是完整性的完整来源:

public class Foo : IDisposable
{
    private Bar _Bar;
    private Baz _Baz;
    private bool _IsDisposed;

    ~Foo() { Dispose(false); }

    public void Dispose(bool disposing)
    {
        if (!_IsDisposed)
        {
            if (disposing)
            {
                DisposeObject(ref _Baz);
                DisposeObject(ref _Bar);
            }
        }

        _IsDisposed = true;
    }

    private void DisposeObject(ref IDisposable obj)
    {
        try
        {
            if (obj == null) 
                return;
            obj.Dispose();
            obj = null;
        } catch (ObjectDisposedException) { /* Already Disposed... */ }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

public class Bar : IDisposable
{
    public void Dispose() {}
}

public class Baz : IDisposable
{
    public void Dispose() {}
}
Run Code Online (Sandbox Code Playgroud)

[结果]
我删除了将参数设置为null(obj = null;)的代码,DisposeObject 因此最终的代码变为了.

    public void Dispose(bool disposing)
    {
        if (!_IsDisposed)
        {
            if (disposing)
            {
                DisposeObject(_Baz);
                DisposeObject(_Bar);
            }
        }

        _IsDisposed = true;
    }

    private void DisposeObject(IDisposable obj)
    {
        try
        {
            if (obj == null) 
                return;
            obj.Dispose();
        } catch (ObjectDisposedException) { /* Already Disposed... */ }
    }
Run Code Online (Sandbox Code Playgroud)

Dan*_* C. 5

这是您的示例的一个选项(目前无法针对编译器进行验证,但您会明白这一点):

private void DisposeObject<T>(ref T obj) where T : IDisposable
{
    // same implementation
}
Run Code Online (Sandbox Code Playgroud)

要打电话,请使用

DisposeObject<Baz>(ref _Baz);
DisposeObject<Bar>(ref _Bar);
Run Code Online (Sandbox Code Playgroud)

正如其他注释中所指出的,您获得的编译器错误有其自己的目的(阻止您在方法中分配一些其他类型的IDisposable,从而导致状态不一致).