In C#, if I want to deterministically clean up non-managed resources, I can use the "using" keyword. But for multiple dependent objects, this ends up nesting further and further:
using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (StreamReader sr = new StreamReader(bs))
{
// use sr, and have everything cleaned up when done.
}
}
}
In C++, I'm used to being able to use destructors to do it like this:
{
FileStream fs("c:\file.txt", FileMode.Open);
BufferedStream bs(fs);
StreamReader sr(bs);
// use sr, and have everything cleaned up when done.
}
Is there a better way in C# to do this? Or am I stuck with the multiple levels of nesting?
This makes for a much larger net plus in lines of code, but a tangible gain in readability:
Where StreamWrapper is defined here:
With some effort, StreamWrapper could be refactored to be more generic and reusable.
Instead of nesting using statements, you can just write out the .Dispose calls manually - but you'll almost certainly miss one at some point.
Either run FxCop or something else that can make sure that all IDisposable-implementing type instances have a .Dispose() call, or deal with the nesting.
I have implemented solutions like Michael Meadows's before, but his
StreamWrapper
code doesn't take into account if theDispose()
methods called on the member variables throw an exception for one reason or another, the subsequentDispose()
es will not be called and resources could dangle. The safer way for that one to work is:you can omit the curly braces, like:
or use the regular try finally approach: