[英]How to cast List<ClassB> to List<ClassA> when ClassB inherits from ClassA?
我將json字符串反序列化為List<ClassB>
,現在我想在將它從BindModel
方法返回之前將其BindModel
為List<ClassA>
。 我需要進行強制轉換,因為這些方法需要獲取List<ClassA>
。
為什么我在施法時遇到錯誤? 畢竟, ClassB
繼承自ClassA
。 我該怎么辦?
PS這個問題從這篇文章擴展而來。 在線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; }
}
您可以使用
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
我會像這樣投射列表:
var listB = GetListOfB(); // returns List<B>
var listA = listB.Select(q => (A)q).ToList();
這對你有用嗎?
您不能將SubType列表強制轉換為SuperType列表。 假設我有一個Tortoises列表,我可以把它放到一個動物列表中。 然后我可以將一只獅子添加到陸龜列表中,但獅子的類型不正確。
但是,對於enumerables,你可以這樣做。 以前的海報是在說,你可以投子類型的列表,以超的IEnumerable完全正確的。 實際上,在C#4中,IEnumerable SubType是一個IEnumerable的SuperType 。 這是因為泛型參數被指定為out參數。
要從List<DerivedClass>
創建List<BaseClass>
, List<DerivedClass>
是不夠的,正如其他答案所指出的那樣。 您需要構建一個新列表。
我對其他答案建議的代碼並不是特別滿意,所以我提供了自己的解決方案。 我會這樣做:
var baseClassList = new List<BaseClass>(derivedClassList.Cast<BaseClass>());
有人可能更喜歡這個:
var baseClassList = derivedClassList.Cast<BaseClass>().ToList();
我更喜歡第一個,因為它可以很容易地將類型從List<T>
更改為使用帶有IEnumerable<T>
的構造函數的任何其他集合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.