Saturday, September 10, 2011

Combining Multiple C# Using Statements

I sometimes find myself having to write the following code where I need to use multiple Using statements and end up nesting them.

using (StreamReader reader = new StreamReader("FileToProcess.txt";))
{
    using (StreamWriter results = new StreamWriter("Results.txt"))
    {
        using (StreamWriter errors = new StreamWriter("Errors.txt"))
        {
            // Read/Write from/to the files as needed
        }
    }
}

There is nothing wrong with this, but I do not like having too much indentation in my code.  When I searched on the web to see if there are other ways to avoid nesting multiple Using statements, I found the post on StackOverflow:
http://stackoverflow.com/questions/966086/using-various-types-in-a-using-statement-c

Basically, the statement inside the using is like a variable declaration, so if you happen to be declaring multiple variables of same type that all implement IDisposable, then you could combine them inside a single using declaration.  For example, I could combine results and errors variables in the above code as follows:

using (StreamReader reader = new StreamReader("FileToProcess.txt"))
{
    using (StreamWriter results = new StreamWriter("Results.txt"), 
            errors = new StreamWriter("Errors.txt"))
    {
        // Read/Write from/to the files as needed
    }
}

It is a little better, but it would be nice if I can get rid of the second using statement or nesting another level, so I have modified the original code to as follows:

StreamReader reader;
StreamWriter results, errors;
using (IDisposable _reader = new StreamReader("FileToProcess.txt"),
    _results = new StreamWriter("Results.txt"),
    _errors = new StreamWriter("Errors.txt"))
{
    reader = (StreamReader)_reader;
    results = (StreamWriter)_results;
    errors = (StreamWriter)_errors;

    // Read/Write from/to the files as needed
}

Granted I have more lines of code that does the same thing as the original code plus extra casting for the sake of a single using statement and eliminating multiple levels of nesting, I however prefer this later version of code.
While getting ready to write this report, I was searching StackOverflow(SO) for the above link as I found that post a while back. While searching SO, I found this other post where it shows how you could write separate usings one below another without having to nest them.
http://stackoverflow.com/questions/1329739/nested-using-statements-in-c

Taking a cue from this post, I have changed the code as follows:

using (StreamReader reader = new StreamReader("FileToProcess.txt"))
using (StreamWriter results = new StreamWriter("Results.txt"))
using (StreamWriter errors = new StreamWriter("Errors.txt"))
{
    // Read/Write from/to the files as needed
}

This is the ideal solution in my opinion. You could list all of usings one by one explicitly and do not have to nest them. I understand, I originally said, I wanted to put all of them in a single using statement, but my main objective is to avoid nesting and this syntax that I was not aware of until now suits me the best.

Thanks for reading.

Sonny

No comments: