2009-09-23 13 views
6

Supponiamo che io sono un TestCollection classe che viene utilizzato per contenere oggetti di tipo di test ed è definito comeAggiunta IEnumerable <T> alla classe derivata da CollectionBase

public class TestCollection : CollectionBase 

Questo mi permette di scorrere l'insieme sia come

foreach(object o in collection) 
... 

o

foreach(Test t in collection) 

ma non consente io per usare nuove query Linq.

Se cambio la definizione della classe per

public class TestCollection : CollectionBase, IEnumerable<Test> 

e aggiungere un metodo

public new IEnumerator<Test> GetEnumerator() 
{ 
    foreach (Test o in this.List) 
     yield return o ; 
} 

quindi LINQ query sono disponibili.

Tuttavia questo nuovo metodo non è solo chiamato per le query LINQ, ma è anche chiamato in codice legacy (cioè durante il foreach (oggetto o della raccolta) e foreach (Test in Collection).

C'è qualche differenza tra il vecchio modo di iterare attraverso la raccolta e questo nuovo modo assumendo che tutti gli elementi nella raccolta siano di tipo Test? Sono consapevole che l'aggiunta del metodo IEnumerator farà sì che il programma generi un'eccezione se trova qualsiasi altro tipo oltre a Test , ma voglio sapere se ho trascurato qualcosa

risposta

2

No, vedrete risultati identici e sperimenterete solo un livello aggiuntivo di riferimento indiretto (poiché il nuovo metodo GetEnumerator chiama semplicemente il metodo GetEnumerator esistente e ne trasmette l'output).

0

Il IEnumerator<T> compilato da un iteratore non implementa il metodo Reset. EDIT: Voglio dire che getterà un NotImplementedException.

Non c'è niente di sbagliato in questo, ma se si desidera il metodo Reset, è necessario scrivere la propria classe di iteratore, che non è difficile.

+1

No; * lo implementa * come lancio di una "NotImplementedException". I blocchi iteratori vanno bene per questo scopo. –

+0

Ecco cosa intendevo. – SLaks

13

Dato che ci si trova in 2.0 (o sopra), forse si eredita semplicemente da Collection<T>?

public class TestCollection : Collection<Test> { 
    // your extra code here 
} 

poi si arriva IList<T>, ICollection<T>, IEnumerable<T> gratuitamente, e virtual metodi che è possibile override per mettere il timbro sul comportamento.

+0

+1 È anche una buona idea. –

+0

+1 .. sono d'accordo con questo. –

+2

La modifica di un tipo di base è una modifica che si interrompe: se la classe è già stata spedita, questa operazione non dovrebbe essere eseguita. – SLaks

Problemi correlati