2016-06-29 14 views
6

Diciamo che ho definito una classe MyDisposable : IDisposable. So che posso fornire un elenco hardcoded di IDisposable oggetti al using dichiarazione:C'è un modo per avere un'istruzione using con target creati dinamicamente?

using (MyDisposable firstDisposable = new MyDisposable(), 
    secondDisposable = new MyDisposable()) 
{ 
    // do something 
} 

Ora diciamo che ho un paio di metodi che eseguono operazioni su una raccolta dei miei oggetti usa e getta, e voglio fare questo all'interno di una dichiarazione using. Potrebbe assomigliare a questo (ma questo non funziona, naturalmente, perché il blocco utilizzando aspetta uno o più oggetti IDisposable e sto passando un oggetto di raccolta singolo):

using (var myDisposables = GetMyDisposables()) 
{ 
    foreach (var myDisposable in myDisposables) 
    { 
     DoSomething(myDisposable); 
     DoSomethingElse(myDisposable); 
    } 
} 

Qui ci sono gli altri metodi solo per maggiore chiarezza :

static List<MyDisposable> GetMyDisposables() 
{ 
    throw new NotImplementedException(); // return a list of MyDisposable objects 
} 

static void DoSomething(MyDisposable withMyDisposable) 
{ 
    // something 
} 

static void DoSomethingElse(MyDisposable withMyDisposable) 
{ 
    // something else 
} 

c'è qualche modo per ottenere questo risultato con l'affermazione using? O devo semplicemente buttare via la dichiarazione e smaltirla manualmente?

+6

è possibile creare un 'DisposableCollection : IDisposable, IEnumerable dove T: IDisposable' – Lee

+0

È possibile scrivere 'IDisposable' che incapsula una raccolta degli oggetti' MyDisposable' e dispone di tutti i suoi elementi quando si smaltirlo. –

+0

Perché non aggiungi la tua istruzione using all'interno del blocco foreach? – peinearydevelopment

risposta

7

Un approccio che si può prendere è quello di fare una raccolta di IDisposable oggetti, che è anche IDisposable:

class CollectionOfDisposable<T> : IDisposable where T : IDisposable { 
    public IList<T> Members {get; private set;} 
    public CollectionOfDisposable(IEnumerable<T> members) { 
     Members = members.ToList(); 
    } 
    public void Dispose() { 
     var exceptions = new List<Exception>(); 
     foreach (var item in Members) { 
      try { 
       item.Dispose(); 
      } catch (Exception e) { 
       exceptions.Add(e); 
      } 
     } 
     if (exceptions.Count != 0) { 
      throw new AggregateException(exceptions); 
     } 
    } 
} 

Ora è possibile scrivere questo:

using (var myDisposables = GetMyDisposables()) { 
    foreach (var myDisposable in myDisposables.Members) { 
     DoSomething(myDisposable); 
     DoSomethingElse(myDisposable); 
    } 
} 

static CollectionOfDisposable<MyDisposable> GetMyDisposables() { 
    throw new NotImplementedException(); // return a list of MyDisposable objects 
} 
+0

Siamo tutti d'accordo sul fatto che questa classe debba esistere nella FCL? Non riesco a trovare nulla di simile. Beh, in realtà, ho trovato questo ['System.Reactive.Disposables.CompositeDisposable'] (https://msdn.microsoft.com/en-us/library/system.reactive.disposables.compositedisposable (v = vs.103). aspx) ma richiede queste [Estensioni reattive] (https://msdn.microsoft.com/en-us/library/hh242985 (v = vs.103) .aspx). –

3

Dovrai creare il tuo tipo che implementa IDisposable e accetta una raccolta di oggetti usa e getta nel suo costruttore, trattenendoli e smaltendoli tutti al momento del suo smaltimento.

Problemi correlati