Home > Software design >  C# Wrap Array of StreamWriters in an using block (Or any smarter way)
C# Wrap Array of StreamWriters in an using block (Or any smarter way)

Time:08-31

I'm Writing to 2 files at a time from a row in a csv, basically I have a list of rows that some have errors so I want to create a log file with detailed errors per row and a new csv with all these rows that had errors, so I'm opening 2 streamwriters at a time, so instead of doing a using block within a using block im doing

using (var writer = new StreamWriter[] { new StreamWriter(infoFolderPath   "/Import Errors.txt"), new StreamWriter(infoFolderPath   "/Failed Import Rows.csv") })
{
    foreach (var err in rowsWithErrors)
    {
        writer[0].WriteLine(Write row error here...);
        writer[1].WriteLine(Write row in csv here...);
    }
}

But the problem with this is I get an error 'StreamWriter[]': type used in a using statement must be implicitly convertible to 'System.IDisposable'. I understand that I need to be able to dispose of the Stream after its done and the using block cant find the Dispose method because its an array of type stream and not of type stream.

So my question is, is there a way to make this work or a smarter way to write to a few files?

(please don't answer to make 2 using statements because I'm writing to more then 2 files I just simplified for the question to be easy to understand...)

CodePudding user response:

Change it to a try/finally block instead which is what using equates to.

var writer = new StreamWriter[] { new StreamWriter(infoFolderPath   "/Import Errors.txt"), new StreamWriter(infoFolderPath   "/Failed Import Rows.csv") }
try
{
    foreach (var err in rowsWithErrors)
    {
        writer[0].WriteLine(Write row error here...);
        writer[1].WriteLine(Write row in csv here...);
    }
}
finally
{
    foreach(var w in writer)
    {
      w.Dispose();
    }
}

Based on the comments it is always 4 streams. I would personally just stack the using statements (or var if using a supported c# version). Notice that there is no additional indentation for each additional using statement. This also allows you to give meaningful names to your variables (unlike my code example below).

using (var writer1 = new StreamWriter(infoFolderPath   "/Import Errors.txt"))
using (var writer2 = new StreamWriter(infoFolderPath   "/Failed Import Rows.csv"))
using (var writer3 = new StreamWriter(infoFolderPath   "/other.txt"))
using (var writer4 = new StreamWriter(infoFolderPath   "/other2.txt"))
{
    foreach (var err in rowsWithErrors)
    {
        writer1.WriteLine(Write row error here...);
        writer2.WriteLine(Write row in csv here...);
        writer3.WriteLine(Write row error here...);
        writer4.WriteLine(Write row in csv here...);
    }
}

If you are using c# 8 or higher you can reduce the nesting even more with var using.

using var writer1 = new StreamWriter(infoFolderPath   "/Import Errors.txt");
using var writer2 = new StreamWriter(infoFolderPath   "/Failed Import Rows.csv");
using var writer3 = new StreamWriter(infoFolderPath   "/other.txt");
using var writer4 = new StreamWriter(infoFolderPath   "/other2.txt");

foreach (var err in rowsWithErrors)
{
    writer1.WriteLine(Write row error here...);
    writer2.WriteLine(Write row in csv here...);
    writer3.WriteLine(Write row error here...);
    writer4.WriteLine(Write row in csv here...);
}
  • Related