Cast vs OfType en LINQ
LINQ no puede trabajar con colecciones que no implementen la interfaz IEnumerable<T>. Esto es debido a que no se encuentran fuertemente tipadas. Por este motivo dentro de un ArrayList podríamos encontrarnos tanto elementos de tipo string como de tipo integer.
ArrayList products = new ArrayList{ new Product { Name= "Product1"}, new Product { Name= "Product2"}, 1
};
Esto ocurre con todos los tipos de colecciones que se encuentran dentro del namespace System.Colleccitons:
En este punto entran en juego los métodos Cast<T> y OfType<T>. Estos métodos son capaces de convertir una colección que no implemente la interfaz IEnumerable<T>, en una que si lo haga. De esta manera es posible utilizar este tipo de colecciones dentro de LINQ.
var items = products.OfType<Product>()
.Where(p => p.Name.EndsWith("1"));
foreach (var item in items)
{ Console.WriteLine(item.Name);
}
Product1
La diferencia que existe entre los dos métodos es que en el caso de Cast, si dentro de la colección se encuentra un elemento que no pueda ser convertido al tipo marcado, se lanzará una excepción. En el caso de OfType, si se encuentra un elemento que no se pueda convertir al tipo indicado, este se desecha.
var items = products.Cast<Product>()
.Where(p => p.Name.EndsWith("1"));
var item
in items)
{ Console.WriteLine(item.Name);
}
Product1
Invalid cast from ‘Sistem.Int32’ to SampleLinq.Product’.