2010-10-25 8 views
153

Conozco dos métodos de conversión de tipos a IEnumerable desde un Arraylist en Linq y me pregunto en qué casos usarlos?Cuándo usar Cast() y Oftype() en Linq

por ejemplo

IEnumerable<string> someCollection = arrayList.OfType<string>() 

o

IEnumerable<string> someCollection = arrayList.Cast<string>() 

¿Cuál es la diferencia entre estos dos métodos y dónde debería aplicar cada caso?

Respuesta

236

OfType - devuelve solo los elementos del tipo x.
Cast - intentará convertir todos los elementos en tipo x. si algunos de ellos no son de este tipo obtendrá InvalidCastException

EDITAR
por ejemplo:

object[] objs = new object[] { "12345", 12 }; 
objs.Cast<string>().ToArray(); //throws InvalidCastException 
objs.OfType<string>().ToArray(); //return { "12345" } 
+0

aplausos por eso.Intenté ambos de antemano, pero ambos tenían elementos de todo tipo, por lo que no pude ver la diferencia. –

+6

@SLaks señala correctamente que debe usar 'Cast ' cuando esté seguro de que la colección solo contiene elementos 'T'. 'OfType ' es más lento debido a la comprobación de tipo 'is'. Si la colección es del tipo 'IEnumerable ', 'Cast ' simplemente convertirá toda la colección en 'IEnumerable ' y evitará enumerarla; 'OfType ' todavía enumerará. ref: http://stackoverflow.com/questions/11430570/why-is-oftype-faster-than-cast – hIpPy

+19

Incluso en los casos en que '.Cast ()' no arroja cuando se enumera, es ** no es ** equivalente a '.OfType ()'. La razón es que los valores ** 'null' ** siempre se omiten por' .OfType () '. Un ejemplo: 'new System.Collections.ArrayList {" abc "," def ", null," ghi ",} .OfTipo () .Count()' solo dará '3'; la expresión similar con '.Cast ()' evalúa a '4'. –

2

Cast() tratará de emitir todos los elementos de la colección (y lanzar una excepción si el elemento es del tipo incorrecto) mientras que OfType() devolverá solo elementos del tipo apropiado.

83

http://solutionizing.net/2009/01/18/linq-tip-enumerable-oftype/

Fundamentalmente, moldeada() se implementa como esto:

public IEnumerable<T> Cast<T>(this IEnumerable source) 
{ 
    foreach(object o in source) 
    yield return (T) o; 
} 

Usando una conversión explícita se realiza bien, pero dará lugar a un InvalidCastException si falla el reparto. Una variación pero útil menos eficiente en esta idea es OfType():

public IEnumerable<T> OfType<T>(this IEnumerable source) 
{ 
    foreach(object o in source) 
    if(o is T) 
     yield return (T) o; 
} 

La enumeración de regresar sólo incluirá elementos que con seguridad se puede convertir al tipo especificado.

2

OfType filtrará los elementos para devolver solo los del tipo especificado. Cast se bloqueará si un elemento no se puede convertir al tipo de destino.

26

Debe llamar al Cast<string>() si sabe que todos los artículos son string s.
Si algunos de ellos no son cadenas, obtendrá una excepción.

Debe llamar al OfType<string>() si sabe que algunos de los artículos no son string sy usted no desea esos artículos.
Si algunos de ellos no son cadenas, no estarán en el nuevo IEnumerable<string>.

+0

Esta respuesta es (actualmente) la única que da un consejo explícito sobre cuándo usar qué método. – CodeFox

2

Cast intentará convertir todos los elementos al tipo T. Este lanzamiento puede fallar o lanzar una excepción. OfType devolverá un subconjunto de la colección original y devolverá solo objetos del tipo T.

3

Se debe tener en cuenta que el Cast (Of T) se puede usar en IEnumerable a diferencia de otras funciones LINQ, por lo que si alguna vez hay un caso donde necesita usar LINQ en una colección o lista no genérica como ArrayList, puede usar Cast (Of T) para convertir a IEnumerable (Of T) donde LINQ puede funcionar.

Cuestiones relacionadas