Loszuwerden geschachtelte mit(...) Aussagen
Manchmal brauche ich mehrere Einweg-Objekte, die innerhalb einer Funktion. Häufigste Fall ist, dass StreamReader und StreamWriter, aber manchmal ist es sogar mehr als das.
Verschachtelte Anweisungen schnell und hässlich Aussehen.
Um dies zu beheben habe ich eine kleine Klasse, die sammelt IDisposable-Objekten und veräußert er diese, wenn er sich selbst entsorgt.
public class MultiDispose : HashSet<IDisposable>, IDisposable
{
public MultiDispose(params IDisposable[] objectsToDispose)
{
foreach (IDisposable d in objectsToDispose)
{
this.Add(d);
}
}
public T Add<T>(T obj) where T : IDisposable
{
base.Add(obj);
return obj;
}
public void DisposeObject(IDisposable obj)
{
obj.Dispose();
base.Remove(obj);
}
#region IDisposable Members
public void Dispose()
{
foreach (IDisposable d in this)
{
d.Dispose();
}
}
#endregion
}
Also mein code sieht jetzt wie folgt aus:
using (MultiDispose md = new MultiDispose())
{
StreamReader rdr = md.Add(new StreamReader(args[0]));
StreamWriter wrt = md.Add(new StreamWriter(args[1]));
WhateverElseNeedsDisposing w = md.Add(new WhateverElseNeedsDisposing());
//code
}
Gibt es etwas falsch mit diesem Ansatz, die Probleme verursachen können die Straße hinunter?
Ich verließ die Entfernen-Funktion geerbt, die aus der HashSet mit Absicht so, dass die Klasse flexibler gestaltet werden.
Sicherlich Missbrauch dieser Funktion kann zu Objekten führen, die nicht ordnungsgemäß entsorgt, aber dann gibt es viele andere Möglichkeiten, um zu Schießen selbst in den Fuß, ohne zu dieser Klasse.
- -1: Frage zu subjektiv
- IMO - nur eine schlechte Idee, auf vielen Ebenen. Ich hoffe, Sie finden die Anleitung hier, um Ihrer selbst Willen, und dass von jedem team-Mitglieder arbeiten mit. Sehen Skeet-Antwort für etwas Klarheit.
- seien Sie nicht dumm. Wir haben Fragen über die Benennung, Kapital und Einrücken die ganze Zeit hier. Diese ist ziemlich beträchtlichen in-Vergleich.
- Ok, ich werde versuchen, nicht zu sein... 🙂
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie einfach diesen:
Einige wenige Punkte, die über das Allgemeine Prinzip:
using
Aussagen ohne zusätzliche KlammernWenn Sie zwei Variablen des gleichen Typs, verwenden Sie eine einzige Anweisung:
Nun vorausgesetzt, Sie wirklich wollen, gehen Sie mit diesem:
Add
.HashSet<T>
oder in der Tat jede Sammlung. Sie sollten einfach nur eine Liste innerhalb der Klasse als private-member-variable.Dispose
Aufrufe fehl, keines der anderenDispose
Anrufe gemacht werden; mit einem traditionellenusing
Anweisung, jeden Anruf zuDispose
innerhalb seiner eigenenfinally
block.Grundsätzlich, ich denke, es ist eine schlechte Idee. Schachtelung auf zwei Ebenen tief ist weit entfernt von schmerzhaft; verschachteln von drei relativ selten; nisten vier oder mehr stark schlägt das refactoring. Anstatt zu versuchen, mit dem Schmerz umzugehen tiefer verschachteln, sollten Sie das design entfernt sich von ihm.
Vielleicht ist es nur, dass Sie gezeigt haben, ein einfaches Beispiel, aber ich denke, das folgende ist mehr lesbar.
Können Sie machen verschachtelten
using
Aussagen hübscher aus, als nur mit ein paar Klammern:Ihre Frage zu beantworten, die Sie entsorgen müssen in der entgegengesetzten Reihenfolge der Zugabe.
Daher können Sie nicht verwenden, eine
HashSet
.Auch, es gibt keinen Grund zum aussetzen der Liste der
IDisposable
s nach außen.Sie sollten daher nicht Erben jede collection-Klasse, und stattdessen pflegen Sie einen privaten
List<IDisposable>
.Sollten Sie dann öffentlich
Add<T>
undDispose
Methoden (und keine anderen Methoden), und eine Schleife durch die Liste rückwärts inDispose
.Persönlich würde mich wahnsinnig. Wenn Sie finden, geschachtelte Anweisungen, um ärgerlich zu sein, Sie könnte wieder in der try/finally-syntax. Dispose-Methoden sollen keine exceptions werfen man könnte also davon ausgehen, dass mehrere Verbrauchsmaterialien hätte nicht sein müssen, einzeln verpackt in try/finally-Blöcken.
Erwähnenswert ist auch, dass Sie brauchen nur eine Reihe von Klammern für die angrenzenden Blöcke wie:
Ich habe zu sagen, ich Stimme nicht mit den Leuten, die wollen, zu tun, mit Aussagen, die einer nach dem anderen wie:
Meiner Meinung nach, das ist sehr unleserlich - mit jedem code-block, der ist nicht verpackt, ist einfach nur schlechter Stil und kann zu Problemen führen, es sei denn, alle Entwickler arbeiten daran sind sehr vorsichtig.
Ich würde mal sagen, dass Sie auf Augenhöhe mit so etwas wie:
Technisch nicht ungültig, aber es ist schrecklich, zu betrachten.
Ich bin damit einverstanden, dass die MultiDispose Konzept ist wahrscheinlich nicht die beste Idee, aufgrund der Tatsache, dass es nicht eine akzeptierte Muster, aber ich definitiv würde nicht diesen Weg gehen, entweder. Wenn Sie können nicht die Dinge brechen in kleinere Stücke, dann würde ich vorschlagen, dass nur das Leben mit den verschachtelten aufzuhalten der Benutzung.