So basically i have this method.
public List<Customer> FilterCustomersByStatus(List<Customer> source, string status)
{
return (List<Customer>)source.Where(c => c.Status == status);
}
I throws me an error that it cannot cast:
Unable to cast object of type 'WhereListIterator`1[AppDataAcces.Customer]' to type 'System.Collections.Generic.List`1[AppDataAcces.Customer]'.
Why...? since the underlying type is the same, does the Enumerable.Where create a new instance of WhereListIterator and if so why would anyone do this, because thats an unnecessary loss of performance and functionality since i always have to create a new list (.ToList())
does the Enumerable.Where create a new instance of
WhereListIterator
Yes.
and if so why would anyone do this
Because it allows lazy streaming behavior. Where
won't have to filter all the list if its consumer wants only first or second entry. This is normal for LINQ.
because thats an unnecessary loss of performance and functionality since i always have to create a new list (.ToList())
That "loss of performance and functionality" comes from your design. You don't need List<Customer>
after filtering, because it's pointless to do any modifications on it.
Update: "why is it implemented so"
Because it it implemented over IEnumerable
, not IList
. And thus it looks like IEnumerable
, it quacks like IEnumerable
.
Besides, it's just so much easier to implement it this way. Imagine for a moment that you have to write Where
over IList
. Which has to return IList
. What should it do? Return a proxy over original list? You'll suffer huge performance penalties on every access. Return new list with filtered items? It'll be the same as doing Where().ToList()
. Return original list but with all non-matching items deleted? That's what RemoveAll
is for, why make another method.
And remember, LINQ tries to play functional, and tries to treat objects as immutables.
As others pointed out, you need to use ToList
to convert the result to List<T>
.
The reason is that Where
is lazily evaluated, so Where
does not really filter the data.
What it does is create an IEnumerable
which filters data as needed.
Lazy evaluation has several benefits. It might be faster, it allows using Where
with infinite IEnumerable
s, etc.
ToList
forces the result to be converted to List<T>
, which seems to be what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With