I deserialized json string to List<ClassB>
and now I want to cast it to List<ClassA>
before I return it from BindModel
method. I need casting because the methods expects to get List<ClassA>
.
Why I get error while casting? After all, ClassB
inherits from ClassA
. What should I do?
PS this question is extended from this post . In line new DataContractJsonSerializer(typeof(List<ClassB>));
instead of List<ClassB>
the type will be constructed at runtime.
public override object BindModel(...)
{
var serializer = new DataContractJsonSerializer(typeof(List<ClassB>));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("[{\"id\":\"1\",\"name\":\"name\"}]"));
var list = serializer.ReadObject(ms);
return (List<ClassA>)list;
}
[KnownType(typeof(ClassA))]
[DataContract]
public class ClassA
{
public ClassA();
}
[KnownType(typeof(ClassB))]
[DataContract]
public class ClassB : ClassA
{
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "name")]
public string CategoryName { get; set; }
}
You can use
Cast<T>()
For example:
List<A> listOfA = new List<B>().Cast<A>();
This in fact is inferior to Linq and is implemented on IEnumerable
rather than IEnumerable<T>
but still is useful. It is not efficient since as I said, it tries to cast it.
Remember List does not allow for covariance which is a nuisance. It is preferable to use IEnumerable<T>
as interface rather than List.
You can say:
IEnumerable<B> listOfB = new List<B>();
IEnumerable<A> listOfA = listOfB; // no casting required
You can use the Cast Method .
return list.Cast<ClassB>();
Have a look at this question about Co and Contra Variance
I would cast the lists like this:
var listB = GetListOfB(); // returns List<B>
var listA = listB.Select(q => (A)q).ToList();
Will that work for you?
You can't cast a List of SubType to a List of SuperType . Suppose I have a list of Tortoises, and I was able to cast it to a list of Animals. Then I could add a lion, to a list of Tortoises, but a Lion isn't of the correct type.
With enumerables, you can do this, however. The previous posters are quite correct in saying that you can cast a List of SubType to an IEnumerable of SuperType . In fact, in C# 4, and IEnumerable SubType is an IEnumerable of SuperType . This is because the generic parameter is specified as an out parameter.
To create a List<BaseClass>
from a List<DerivedClass>
, a cast will not suffice, as other answers have noted. You need to construct a new list.
I'm not particularly happy with the code that other answers have suggested, though, so I'm offering my own solution. I would do it this way:
var baseClassList = new List<BaseClass>(derivedClassList.Cast<BaseClass>());
Some might prefer this:
var baseClassList = derivedClassList.Cast<BaseClass>().ToList();
I prefer the first one because it makes it easy to change the type from List<T>
to any other collection with a constructor that takes an IEnumerable<T>
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.