Reputation: 5792
I have a class Literal and a Tag is inheriting from it.
I would like to do the following but I am getting
Unable to cast object of type 'WhereListIterator`1[Core.Literal]' to type 'System.Collections.Generic.List`1[Core.Tag]'.
private List<Literal> literals;
public List<Tag> Tags
{
get { return (List<Tag>)literals.Where(x => x is Tag); }
}
thanks
Upvotes: 10
Views: 16073
Reputation: 5404
You would be better off doing:
literals.OfType<Tag>().ToList();
This gives you a List<Tag>
.
You can also do:
var asList = new List<Tag>(literals.OfType<Tag>());
Casting simply does not work because LINQ works in terms of either IEnumerable<T>
or IQueryable<T>
which neither use List as a backing implementation for the results. The second method I posted uses a constructor overload of List<T>
the takes in an IEnumerable<T>
as its initial collection of objects. Also in this scenario the OfType<T>
method from LINQ is a much cleaner, shorter form of essentially filtering a list with Where(x -> x is T)
.
Also, OfType<T>
in this scenario is a much better idea, because the result is an IEnumerable<T>
of your target type. Where(x => x is T)
will return an IEnumerable<T>
of the original source's type. So that's why (List<Tag>)literals.Where(x => x is Tag).ToList()
emit an error for invalid casts.
More information on ToList
More information on OfType
Upvotes: 36
Reputation: 6805
List<Tag>)literals.Where(x => x is Tag).ToList();
or even better :
literals.OfType<Tag>();
then you can create a new list from it:
new List<Tag>(literals.OfType<Tag>());
Upvotes: 1
Reputation: 700242
The Where
method returns the same type as the source, so you would have to cast each item, then use the ToList
method to create a list from the result:
return literals.Where(x => x is Tag).Select(x => (Tag)x).ToList();
You can also us the OfType
method:
return literals.OfType<Tag>().ToList();
Upvotes: 0
Reputation: 1572
try the following:
literals.Where(x => x is Tag).Cast<Tag>().ToList();
it works if Tag
is derived from Literal
Upvotes: 0
Reputation: 2114
How about adding ToList()?
Your getter becomes: literals.Where(x => x is Tag).ToList();
Upvotes: 0
Reputation: 50672
Depending on the effect you want you could do this:
public List<Tag> Tags
{
get { return literals.Where(x => x is Tag).ToList(); }
}
Do realize that this is not a cast but the creation of a list!
Upvotes: 0
Reputation: 9052
literals.Select(x => x as Tag).Where(x => x != null).ToList()
Note that this will return new list. You won't be able to do where and modify original list by this. Also this can be done like this: literals.OfType<Tag>().ToList()
and it will return IList<Tag>
Update: modified type
Upvotes: 7