I am trying to create a general method for disposing an object that implements IDisposable, called DisposeObject()
To make sure I am disposing an object pointed by original reference, I am trying to pass an object by reference.
But I am getting a compilation error that says
The 'ref' argument type doesn't match parameter type
In the below (simplified) code, both _Baz
and _Bar
implement IDisposable.
So the questions are,
[UPDATE]
From provided answers so far, as long as I do not set an IDisposable argument to null, I can simply pass an object by value without using ref
.
I am now having another trouble whether to set disposable objects to null
or not within DisposeObject
method.
Here is the full source for completeness:
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() {}
}
[RESULT]
I removed the code that sets argument to null (obj = null;
) within DisposeObject
So the final code became.
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... */ }
}
There is no need for you to pass by reference, as you're passing a reference type. You should remove the ref
keyword from your method definition. Do this and you shouldn't have any issues, though I'm not sure how this is more effective or clearer than simply calling Dispose()
(other than the fact that you don't have to cast it for explicit implementations and this does a null
check for you).
Edit
Dance, while I hope the discussion that's surrounded this topic has been helpful to you, your original intent doesn't seem to be something that's doable. In order to pass something as ref
, you can't pass a variable that has a type other than what the ref
parameter expects (in other words, you can't pass a variable declared as a class
or other interface
that implements IDisposable
if the ref
parameter is IDisposable
). Because ref
parameters allow assignments to propagate back to the caller, you would open up the possibility of allowing incompatible types being stored in your variable.
Your best bet here is to assign null
yourself if that's what you want. If you want to encapsulate the null
check and ignoring exceptions in to the function that's fine, but ref
will not work for you in this scenario no matter how you slice it, unfortunately.