Ist es schlecht verschachtelte try..catch Blöcke wie diese zu benutzen?
Frage
Ist das eine schlechte Idee? Gibt es einen besseren Weg, um die gleiche Wirkung zu erzielen?
// assume that "name" is a string passed as a parameter to this code block
try
{
MainsDataContext dx = new MainsDataContext();
try
{
Main m = dx.Main.Single(s => s.Name == name);
return m.ID;
}
catch (InvalidOperationException)
{
Guid g = Guid.NewGuid();
Main s = new Main
{
Name = name,
ID = g
};
dx.Mains.InsertOnSubmit(s);
dx.SubmitChanges();
return g;
}
}
catch (Exception ex)
{
// handle this
}
Das Ziel hier ist es, die Identifikation eines Datensatzes zu erhalten, wenn es vorhanden ist, sonst diesen Datensatz erstellen und senden Sie es ID ist.
Lösung
Sie sollten SingleOrDefault verwenden, auf diese Weise, wenn ein Datensatz nicht vorhanden ist der Standardwert für die Klasse zurück, die null ist.
MainsDataContext dx = null;
try
{
dx = new MainsDataContext();
Main m = dx.Main.SingleOrDefault(s => s.Name == name);
if ( m == null)
{
Guid g = Guid.NewGuid();
m = new Main
{
Name = name,
ID = g
};
dx.Mains.InsertOnSubmit(m);
dx.SubmitChanges();
}
return m.ID;
}
catch (Exception ex)
{
// handle this
}
finally
{
if(dx != null)
dx.Dispose();
}
Es ist eine gute Idee, die mit Schlüsselwort zu verwenden, wenn ein Datacontext mit
using ( MainsDataContext dx = new MainsDataContext())
{
Main m = dx.Main.SingleOrDefault(s => s.Name == name);
if ( m == null)
{
Guid g = Guid.NewGuid();
m = new Main
{
Name = name,
ID = g
};
dx.Mains.InsertOnSubmit(m);
dx.SubmitChanges();
}
return m.ID;
}
Andere Tipps
Main m = dx.Main.SingleOrDefault(s => s.Name == name);
if (m == default(Main))
{
// it does not exist
}
else
{
// it does exist
}
Es ist nicht aus der Frage ist, ob der Typ ist (EDIT: Ich habe erkannt, dass es tatsächlich eine Klasse sein muss), daher habe ich Main
eine Klasse oder eine Struktur default()
statt nur zu vergleichen null
zu.
Meine Frage wäre, was Code, den Sie beabsichtigen, hier zu setzen in:
// handle this
Mit dem ersten catch-Block, wissen Sie, dass Einzel () eine InvalidOperationException warf, weil die Sequenz mehr als ein Element enthält oder leer ist.
In der zweiten, könnten Sie alle Arten von Fehlern bekommen. NULL-Verweis, Datenzugriff usw. Wie werden Sie diese behandeln?
Nur fangen, was Sie wissen, wie zu behandeln und als spezifische in dem Ausnahmetyp sein, wie Sie können.
Wie auch immer, ich denke, verschachtelter Try Catch-Blöcke gut sind, wie Geschwister Catch-Blöcke jeweils ein anderes Problem zu kontrollieren. Es ist gut, spezifisch über Fehler zu sein. Die allumfassende sollte nur ein Sicherheitsnetz für die Produktion sein.
Nein, aber Sie könnten den inneren Block in eine externe Methode refector wollen.