I have a
List
but I need a
List
Is there a way to cast this in c
Just in case: I've little C# experience, but if this generic construction means the same thing it does in Java, then you must create a whole new List parametrized by the supertype. In other words, if every instance of Bangle
is also an instance of Akthud
, it does not follow that every List<Bangle>
is also a List<Akthud>
.
The reason for this is that you can have two references to this List<Bangle>
. If the second reference casts and then refers to it as a List<Akthud>
, then it is permitted to add an Akthud
to it - but now the first reference has a List<Bangle>
whose members are not all Bangle
s. Violation!
That being said, David B's answer should indeed do what you want, correctly, AFAICT. (It looks like a copy operation.)
[And if I'm misunderstanding the semantics of C# generics, I hope someone corrects me in a comment!]
ConvertAll seems like a better solution, since it doesn't depend on Linq library and is shorter and more intuitive.
But both of them are rather workarounds, than solutions. Both of them create a new collection with the same data. There should be a support for generic covariance in .net, i.e. upcasting in the generic collections, which would allow you to do that naturally. For example:
List<IDataField> ls = (List<IDataField>)List<InputField>
From my search so far, my conclusion, is that .Net as of 3.5 doesn't support this feature. Hence we have to end up with workarounds.
These are the discussions on the topic:
I don't know that a direct cast would have the desired effect. The rare few times I've done this, it's usually something like:
List<InputField> list = .....
List<IDataField> list2 = new (List<IDataField>((IDataField[])list.ToArray()));
You could also use List.ConvertAll.
Documentation: http://msdn.microsoft.com/en-us/library/73fe8cwf.aspx
Example:
List<IDataField> newList = oldList.ConvertAll(i => i as IDataField);
Both .OfType<T> and .Cast<T> will return a list of T, but the meaning of the two methods is different.
list.OfType() filters the original list and returns all items which are of type T, and skips the ones that are not of that type.
list.Cast() casts all items in the original list to type T, and throws an exception for items which cannot be cast to that type.
In your case both would give the same result, but using .Cast() would communicate your intent a lot more clearly, so I would recommend using that.
List<InputField> list = (from i .... select i).Cast<IDataField>().ToList();
List<InputField> raw = (from i .... select i).ToList();
List<IDataField> result = raw.OfType<IDataField>().ToList();