我将json字符串反序列化为List<ClassB>
,现在我想将其转换为List<ClassA>
,然后再将其返回
BindModel
方法。我需要进行转换,因为方法需要获得List<ClassA>
。
为什么我在投票时会收到错误?毕竟,ClassB
继承自ClassA
。我该怎么办?
P.S。这个问题从this post延伸出来。在行new DataContractJsonSerializer(typeof(List<ClassB>));
而不是List<ClassB>
中,类型将在运行时构建。
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; }
}
答案 0 :(得分:10)
您可以使用
Cast<T>()
例如:
List<A> listOfA = new List<B>().Cast<A>();
这实际上低于Linq ,并且在IEnumerable
而不是IEnumerable<T>
上实施,但仍然有用。它是效率不高,因为正如我所说,它试图施展它。
记住列表不允许协方差,这是一种麻烦。最好使用IEnumerable<T>
作为接口而不是List。
你可以说:
IEnumerable<B> listOfB = new List<B>();
IEnumerable<A> listOfA = listOfB; // no casting required
答案 1 :(得分:6)
答案 2 :(得分:2)
我会像这样投射名单:
var listB = GetListOfB(); // returns List<B>
var listA = listB.Select(q => (A)q).ToList();
这对你有用吗?
答案 3 :(得分:1)
您无法将 SubType 的列表强制转换为 SuperType 列表。假设我有一个Tortoises列表,我可以把它放到一个动物列表中。然后我可以在狮子列表中加一只狮子,但狮子的类型不正确。
使用枚举,你可以这样做。之前的海报非常正确地说您可以将 SubType 的列表强制转换为 SuperType 的IEnumerable。实际上,在C#4中,IEnumerable SubType 是 SuperType 的IEnumerable。这是因为泛型参数被指定为out参数。
答案 4 :(得分:1)
要从List<BaseClass>
创建List<DerivedClass>
,演员阵容是不够的,正如其他答案所指出的那样。您需要构建一个新列表。
我对其他答案建议的代码并不是特别满意,所以我提供了自己的解决方案。我会这样做:
var baseClassList = new List<BaseClass>(derivedClassList.Cast<BaseClass>());
有些人可能更喜欢这个:
var baseClassList = derivedClassList.Cast<BaseClass>().ToList();
我更喜欢第一个,因为它可以很容易地将类型从List<T>
更改为使用带有IEnumerable<T>
的构造函数的任何其他集合。