簡體   English   中英

當ClassB從ClassA繼承時,如何將List <ClassB>轉換為List <ClassA>?

[英]How to cast List<ClassB> to List<ClassA> when ClassB inherits from ClassA?

我將json字符串反序列化為List<ClassB> ,現在我想在將它從BindModel方法返回之前將其BindModelList<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

您可以使用Cast方法

return list.Cast<ClassB>();

看看有關Co和Contra Variance的這個問題

我會像這樣投射列表:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM