2010-05-14 15 views
7

¿Cómo funciona OfType()?¿Cómo funciona OfType <T>() ¿Funciona?

He leído this link sobre lo que está sucediendo, pero cómo sabe exactamente el proveedor de LINQ cómo obtener todos los objetos que coinciden con el tipo especificado. Sé que el IQueryable<T> "encadena" solicitudes y luego evalúa cuando se llama GetEnumerator() (¿verdad?).

Específicamente, quiero saber cómo funciona el marco de comparación de tipo rápidamente? Escribí un método en un proyecto .NET 2.0 que fue como esto (desde 2.0 no soporta este tipo de características):

public IEnumerable<TResult> OfType<TResult>() 
     where TResult : class 
    { 
     foreach (TItem item in this.InnerList) 
     { 
      TResult matchItem = item as TResult; 

      if (matchItem != null) 
      { 
       yield return matchItem; 
      } 
     } 
    } 

¿Es esta la mejor aplicación?

EDIT: Mi principal preocupación con este OfType<T>() es que es rápido .

Respuesta

10

Su implementación actual, por diseño, no admite tipos de valores.

Si quería algo más cercano al método de LINQ OfType, que permite todo tipo, a continuación, intente esto:

public IEnumerable<TResult> OfType<TResult>(IEnumerable source) 
{ 
    foreach (object item in source) 
    { 
     if (item is TResult) 
      yield return (TResult)item; 
    } 
} 
+0

Entonces, ¿es más rápido usar 'is' y luego lanzarlo o es debido a su inclusión de tipos de valores? Pensé que usar as y luego buscar null es más rápido. – TheCloudlessSky

+0

Es posible que la diferencia sea irrelevante debido a optimizaciones de compilador específicas. –

+0

@TheCloudlessSky: si el método se limitara a tratar con tipos de ref, entonces usaría la combinación 'as'/test-for-null como ya lo hizo. La diferencia de velocidad entre usar 'is'/cast y' as'/test-for-null será insignificante, pero si ese nivel de micro-optimización es importante para usted, entonces le sugiero que haga algún benchmarking. – LukeH

0

Parece una buena implementación para mí, pero parece un tipo de implementación específica (se refiere a esto.Lista interna). Si creó un método de extensión (que es compatible con 2.0, ¿no es así?) Que amplía IEnumerable, podría usarlo en cualquier colección enumerable, ¿no es así?

+0

El InnerList es en realidad una 'lista '. También en el trabajo no podemos usar VS2008 (ugh ...) por lo que no podemos apuntar 2.0 con el compilador 3.5. Entonces no, no puedo usar un método de extensión. – TheCloudlessSky

Cuestiones relacionadas