2009-07-20 5 views
7

Ich habe eine Reihe von IDisposable Objekte in einer Nachschlagetabelle (plain old Dictionary <>, gerade jetzt), aber um den Code zu vereinfachen und Fehler zu vermeiden bin ich auf der Suche nach einer Sammlung Klasse, die " besitzt "die Dinge, die es hält, und um das Rad nicht neu zu erfinden" existiert solch eine Klasse bereits?Standard-Sammlung für IDisposable Objekte

Die Spezifikation sollte so sein: - Die Sammlung muss Einwegartikel sein, und wenn es entsorgt wird, sollten alle enthaltenen Artikel ebenfalls entsorgt werden. - Immer wenn ein Artikel entfernt wird, wird zuerst Dispose() -d angezeigt. - Idealerweise wäre die Sammlung generisch mit der Typbeschränkung, die die IDisposable -ness des enthaltenen Typs erzwingt.

ich sorta Zweifel eine solche Klasse existiert, aber ich habe angenehm überrascht von der Existenz von ReadOnlyCollection und ObservableCollection vor ...

Wesentlichen überrascht, ich das Äquivalent der C++ STL-Container möchten aber dann für die CLR ;-).

+0

Es ist eine Weile gewesen ist. Haben Sie eine IDisposableCollection erstellt? Ich könnte es auch benutzen. – JohnV

+0

Nein; Am Ende habe ich die Sammlung eingepackt und nur die (sehr) wenigen Methoden, die ich tatsächlich brauchte - hinzufügen/abrufen/löschen - und einige zusätzliche Funktionen für die bestimmte Sache, an der ich gearbeitet habe (viele Dateisystem-Beobachter), aufgedeckt. –

Antwort

1

Sie suchen nach CompositeDisposable.

using System.Reactive.Disposables; 

    ... 

    CompositeDisposable xs = new CompositeDisposable(Disposable.Empty); 
    xs.Add(Disposable.Empty); 
    xs.Add(Disposable.Empty); 
    xs.Dispose(); 
+0

Nicht generisch.Das ist nicht ganz ideal; aber auch kein großes Problem. –

+0

Rx-Erweiterungen sind nicht Teil von .net-Framework. Für viele ist es kein Problem, aber es ist keine gute Idee, die gesamte Bibliothek nur für eine einfache Klasse zu referenzieren. – arbiter

+0

@arbiter hat einen Punkt, obwohl IMHO gibt es nicht viel Sinn, nicht mit Rx. Sobald Sie die Entscheidung getroffen haben, den gigantischen Overhead der Verwendung von .net in einem Projekt einzubringen, sollte niemand darüber nachdenken, nützliche Bibliotheken einzubringen. –

0

Ich sehe, was Sie fragen, aber wie schwer ist es, Ihre eigene remove-Methode zu erstellen, die das Element entsorgt, bevor Sie es entfernen?

+0

Nicht schwer - aber es wäre sauberer, wenn möglich zu vermeiden. Und es ist nicht nur Entfernen, richtig - jede Methode, die ein Element überschreiben kann, ersetzt implizit ein vorhandenes Element, das auch Dispose() 'd sein müsste. Wenn Ihre Sammlung einige Standardschnittstellen implementiert, kann es einige Varianten dieser Remove/Setter-Funktionen geben, die zu Code Bloat führen. –

2

Von dem, was ich weiß, gibt es nur solche Exits wie IComponents - Container implements IContainer. Für generische IDisposable denke ich, dass Sie keine anderen Optionen haben, als "das Rad neu zu erfinden".

+0

Danke, ich schaue hinein (obwohl es etwas schwer aussieht - die API hat eine Menge Dinge, die ich nicht verwenden würde - das ist vielleicht egal)! –

+0

Container und System.ComponentModel scheinen übermäßig komplex und nicht ausreichend flexibel für den allgemeinen Gebrauch. Kurz gesagt, ich akzeptiere deine Antwort, dass ich keine anderen Möglichkeiten habe, als das Rad neu zu erfinden. –

1

Denken Sie daran, dass Ihre Sammlung möglicherweise nicht die einzige ist, die die Einwegobjekte enthält ... Was ist, wenn ein anderes Objekt (außerhalb der Sammlung) auf eines dieser Objekte verweist? Wenn Sie es entsorgen, wenn die Sammlung entsorgt wird, was würde dann mit dem Objekt geschehen?

Wenn diese Objekte IDisposable für die Verwaltung einiger nicht verwalteter Ressourcen implementieren, stellen Sie sicher, dass sie auch die Finalisierung implementieren und nicht verwaltete Ressourcen dort entsorgen.

+0

Ich kontrolliere derzeit sowohl die Objekte als auch die Sammlung vollständig - das ist also eine hypothetische Situation. Auf jeden Fall; So funktionieren die Dinge mit IDisposables, oder? Ich meine, * jemand * muss sie besitzen (d. H. Eventuell Dispose), und in diesem Fall besitzt der Besitzer zufällig eine variable Anzahl von IDisposables, so dass eine Sammlung am einfachsten wäre. –

0

Wie wäre es etwa so:

public class DisposableEnumerable<T> : IEnumerable<T>, IDisposable where T : IDisposable 
{ 
    IEnumerable<T> Enumerable { get; } 

    public DisposableEnumerable(IEnumerable<T> enumerable) 
    { 
     Enumerable = enumerable; 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     return Enumerable.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return Enumerable.GetEnumerator(); 
    } 

    public void Dispose() 
    { 
     foreach(var disposable in Enumerable) 
     { 
      disposable.Dispose(); 
     } 
    } 
} 
+0

Ich denke, ein fauler Aufzählbarer als Argument ist hier zumindest schwierig; Es ist wichtig zu wissen, dass die Objekte, die Sie passieren, wirklich entsorgt werden. Wenn die Sammlung nicht geändert wird, spielt das natürlich keine Rolle. –

+0

Auch: obwohl es nicht passieren sollte, sollten Sie überlegen, was passiert, wenn ein zugrunde liegendes 'Dispose()' wirft. –

+0

Guter Punkt, danke. –