12
votes

Collection standard pour objets isisposables

J'ai un groupe de Idisposable Objets dans une table de recherche (ancien dictionnaire clair <>, maintenant), mais pour simplifier le code et éviter les erreurs, je cherche une classe de collection qui "possède" les articles qu'il contient et éviter de réinventer la roue - une telle classe existe-t-elle déjà?

La spécification devrait être celle: - La collection doit être jetable et lorsqu'elle est disposée, tous les articles contenus doivent également être disposés. - Chaque fois qu'un article est supprimé, il est Dispose () -D en premier. - Idéalement, la collection serait générique avec la contrainte de type appliquant le iDisposable du type contenu.

Je doute que ce soit une telle classe existe, mais j'ai été agréablement surpris par l'existence de lisonlycollection et observablecollection avant ...

Essentiellement, j'aimerais que l'équivalent des conteneurs STL C ++, mais pour le CLR; -).


2 commentaires

Ça fait un peu de temps. Avez-vous fait une idensposablecolection? Je pourrais l'utiliser aussi.


Non; J'ai fini par envelopper la collection et l'exposition des (très) quelques méthodes que j'ai réellement nécessaires - ajoutez / get / supprimer - et une fonctionnalité supplémentaire pour la chose en question que j'ai travaillé sur (de nombreux observateurs du système de fichiers).


5 Réponses :


0
votes

Je vois ce que vous demandez, mais à quel point il est difficile de faire votre propre méthode Supprimer qui dispose de l'élément avant de le supprimer?


1 commentaires

Pas du tout du tout - mais ce serait plus propre pour l'éviter si possible. Et, ce n'est pas seulement enlever, de droite - aucune méthode qui peut écraser un élément remplace implicitement un élément existant, qui devra être éliminé () »d aussi. Si votre collection implémente quelques interfaces standard, il peut y avoir plusieurs variantes de ces fonctions Supprimer / Setter, menant au code de code.



2
votes

De ce que je sais, il ne fait que quitter cette collection pour les icomponents - Container implémente iContainer . Pour générique Idisposable, je pense que vous n'avez aucune autre option, mais "réinventer la roue".


2 commentaires

Merci, je vais y examiner (bien que cela ait l'air un peu lourd - l'API a un tas de choses que je n'utiliserais pas - cela pourrait ne pas avoir d'importance)!


Le conteneur et le système.componentmodel semblent trop complexes et insuffisamment flexibles pour une utilisation générale. En bref, j'accepte votre réponse que je n'ai aucune autre option, mais pour "réinventer la roue".



1
votes

N'oubliez pas que votre collection pourrait ne pas être la seule contenant les objets jetables ... Et si un autre objet (externe à la collection) fait référence à une de ces? Si vous le disposez lorsque la collection est disposée, qu'est-ce qui arriverait à l'objet?

Si ces objets implémentent Idisposable pour certains ressources non gérés de nettoyage des ressources non gérées, assurez-vous qu'ils appliquent également la finalisation et disposent de ressources non gérées là-bas.


1 commentaires

Je contrôle actuellement entièrement les objets et la collection - il s'agit donc d'une situation hypothétique. Dans tous les cas; C'est comme ça que les choses fonctionnent avec Idisposables, non? Je veux dire, Quelqu'un a pour posséder (c'est-à-dire disposer éventuellement disposer) et, dans ce cas, le propriétaire possède un nombre variable d'Idisposables, une collection serait donc la plus simple.



7
votes

Vous recherchez COMPOSITEDISPONABLE .

    using System.Reactive.Disposables;

    ...

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


3 commentaires

Non générique. Ce n'est pas assez idéal; mais pas un énorme problème non plus.


Les extensions RX ne font pas partie de .NET Framework. Bien que ce ne soit pas un problème pour beaucoup, ce n'est pas une très bonne idée de faire référence à une bibliothèque complète pour une classe triviale.


@Arbiter a un point, bien que l'IMHO, il n'y a pas beaucoup de point dans l'utilisation de RX. Une fois que vous avez décidé de tirer dans la surcharge de Gargantuan d'utiliser .NET dans un projet, personne ne devrait s'agiter de mener à bien des bibliothèques utiles.



0
votes

Que diriez-vous de quelque chose comme ceci:

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();
        }
    }
}


2 commentaires

Je pense qu'un paresseux énumérés comme un argument ici est au moins délicat; Il est important de savoir que les objets que vous passez sont vraiment disposés. Bien sûr, si la collection n'est pas modifiée, cela n'a pas d'importance.


De plus: même si cela ne devrait pas arriver, vous devriez considérer ce qui se passe si un sous-jacent () jette.