367 Stimmen

Verschachtelte using-Anweisungen in C#

Ich arbeite an einem Projekt. Ich muss den Inhalt von zwei Dateien vergleichen und feststellen, ob sie genau übereinstimmen.

Vor einer Vielzahl von Fehlerkontrollen und Validierungen lautet mein erster Entwurf:

  DirectoryInfo di = new DirectoryInfo(Environment.CurrentDirectory + "\\TestArea\\");
  FileInfo[] files = di.GetFiles(filename + ".*");

  FileInfo outputFile = files.Where(f => f.Extension == ".out").Single<FileInfo>();
  FileInfo expectedFile = files.Where(f => f.Extension == ".exp").Single <FileInfo>();

  using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
  {
    using (StreamReader expFile = new StreamReader(expectedFile.OpenRead()))
    {
      while (!(outFile.EndOfStream || expFile.EndOfStream))
      {
        if (outFile.ReadLine() != expFile.ReadLine())
        {
          return false;
        }
      }
      return (outFile.EndOfStream && expFile.EndOfStream);
    }
  }

Es erscheint ein wenig seltsam, verschachtelte using Erklärungen.

Gibt es eine bessere Möglichkeit, dies zu tun?

636voto

SLaks Punkte 832502

Die bevorzugte Methode ist, nur eine öffnende Klammer zu setzen { nach der letzten using Aussage, etwa so:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
using (StreamReader expFile = new StreamReader(expectedFile.OpenRead())) 
{
    ///...
}

152voto

Gavin H Punkte 10060

Wenn die Objekte vom Typ gleiche Art können Sie Folgendes tun

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()), 
                    expFile = new StreamReader(expectedFile.OpenRead()))
{
    // ...
}

40voto

jason Punkte 227577

Wenn die IDisposable s vom gleichen Typ sind, können Sie wie folgt vorgehen:

 using (StreamReader outFile = new StreamReader(outputFile.OpenRead()), 
     expFile = new StreamReader(expectedFile.OpenRead()) {
     // ...
 }

Die MSDN-Seite über using hat eine Dokumentation zu diesem Sprachmerkmal.

Sie können Folgendes tun, unabhängig davon, ob die IDisposable s vom gleichen Typ sind:

using (StreamReader outFile = new StreamReader(outputFile.OpenRead()))
using (StreamWriter anotherFile = new StreamReader(anotherFile.OpenRead()))
{ 
     // ...
}

28voto

Desde C# 8.0 können Sie eine Erklärung verwenden .

using var outFile = new StreamReader(outputFile.OpenRead());
using var expFile = new StreamReader(expectedFile.OpenRead());
while (!(outFile.EndOfStream || expFile.EndOfStream))
{
    if (outFile.ReadLine() != expFile.ReadLine())
    {
         return false;
    }
}
return (outFile.EndOfStream && expFile.EndOfStream);

Dadurch werden die verwendenden Variablen am Ende des Geltungsbereichs der Variablen, d. h. am Ende der Methode, entsorgt.

18voto

Botz3000 Punkte 38010

Wenn es Ihnen nichts ausmacht, die Variablen für Ihren using-Block vor dem using-Block zu deklarieren, können Sie sie alle in der gleichen using-Anweisung deklarieren.

    Test t; 
    Blah u;
    using (IDisposable x = (t = new Test()), y = (u = new Blah())) {
        // whatever...
    }

Auf diese Weise sind x und y nur Platzhaltervariablen vom Typ IDisposable für den using-Block, und Sie verwenden t und u in Ihrem Code. Ich dachte nur, ich sollte es erwähnen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X