2009-09-12 17 views

Respuesta

30

Los métodos de extensión Linq existentes funcionan en objetos que implementar IEnumerable<T>. Supongo que su objeto implementa la interfaz no genérica IEnumerable. En ese caso, puede usar el método de extensión Cast<T> para obtener un contenedor genérico IEnumerable<T>. Por ejemplo, si los elementos son de tipo int:

var wrapper = myObject.Cast<int>(); 

ahora se puede utilizar LINQ en la envoltura

0

No, no puedes. Todos los métodos LINQ son métodos de extensiones para la interfaz IEnumerable<T>.

Así que tendrá que implementar IEnumerable<T> para usar LINQ con sus propias colecciones.

6

No directamente. Se podría escribir bastante fácilmente un SingleShotEnumerable<T> sin embargo:

public sealed class SingleShotEnumerable<T> : IEnumerable<T> 
{ 
    private IEnumerator<T> enumerator; 

    public SingleShotEnumerable(IEnumerator<T> enumerator) 
    { 
     if (enumerator == null) 
     { 
      throw new ArgumentNullException("enumerator"); 
     } 
     this.enumerator = enumerator; 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     if (enumerator == null) 
     { 
      throw new InvalidOperationException 
       ("GetEnumerator can only be called once"); 
     } 
     var ret = enumerator; 
     enumerator = null; 
     return ret; 
    } 

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

Esto es suponiendo que realmente tienen un IEnumerator<T>. Si solo tiene IEnumerator, puede escribir algo similar solo implementando IEnumerable, luego use Cast o OfType para obtener un IEnumerable<T>.

(Nota: esto no es seguro para subprocesos Se podía hacerlo así con las cerraduras si realmente quería..)

A continuación, podría hacer:

var filtered = from person in new SingleShotEnumerable<Person>(personEnumerator) 
       where person.Age > 18 
       select person.Name; 

... pero no podía usar la consulta dos veces

¿Cómo has llegado a la extraña situación de tener solo un IEnumerator<T> de todos modos? Eso es bastante raro. Vea si puede diseñar su camino para evitar tener que hacer algo como lo anterior, que es bastante frágil.

(Una alternativa sería la de "drenar" el IEnumerator<T> a un algo List<T> o similar, pero que tiene problemas relacionados con grandes o potencialmente infinitas secuencias.)

+0

Algunos tipos 'System.Windows.Forms', como' ListViewItemCollection', no parecen implementar 'IEnumerable '. –

+0

@ChrisAkridge: De hecho, solo implementan el 'IEnumerable' no genérico. Pero siempre puedes llamar 'Cast <>' para crear un 'IEnumerable ' desde él. –

Cuestiones relacionadas