You can't directly cast them to each other. Consider the case:
public class Base
{
}
public class Item: Base
{
}
public class EvilItem: Base
{
}
So let's try to cast from List<Item>
to List<Base>
:
List<Item> a = new List<Item>();
List<Base> b = (List<Base>)a;
b.Add(new EvilItem());
Aaand we have a problem. Since List<T>
is a reference-type, both a
and b
are now references to the same list. And we just added an EvilItem
to a List<Item>
- something which should NOT be allowed. But the line b.Add(new EvilItem());
is completely legit, because b
is a List<Base>
.
This goes the other way too. If you create a List<Base>
then you can't cast it to a List<Item>
, because some items in there could be EvilItem
. Or maybe they will get added later.
So .NET forbids such casting.
You have a few options. First, you can create a copy of the list:
b = new List<Base>(a);
Now a
and b
are two completely different lists that just happen to have the same contents. Keep in mind that changing one list will NOT change the other.
Alternatively, if you don't need to modify the list, you can use it as an enumerable instead:
IEnumerable<Base> c = a;
Why this works is a bit of a longer story, but to simplify it - IEnumerable
only allows you to read the list, so you can't do bad things like add EvilItem
to it. Thus it's allowed.
As for why requestList1 = form.item.Cast<Item>()
didn't work - the Cast<T>()
produces an IEnumerable<T>
, not a List<T>
, so you can't assign it. You could change it to requestList1 = form.item.Cast<Base>().ToList()
and that would work - but it would also copy the list. That's another way to do it, actually, although it's a bit longer to write and I also suspect it's a little less efficient (but I don't have proof for that)