數組爲何可使用linq查詢

問題引出數組

  這視乎是個徹底沒必要要進行討論的話題,由於linq(這裏具體是linq to objects)原本就是針對集合類型的,數組類型做爲集合類型的一種固然可使用了。不過我仍是想寫一下,這個問題源於qq羣裏一位朋友的提問:.net的數組類型都隱式繼承了Array類,該類是一個抽象類,而且實現了IEnumerable、ICollection、IList接口。但linq的方法都是針對實現了IEnumerable<T>泛型接口的,Array類並無實現這些泛型接口,爲何可使用這些方法呢?佈局

  linq to objects的本質是經過擴展方法來實現集合的查詢,這些擴展方法定義在一個Enumerable的靜態類中。Enumerable類下的全部擴展方法的第一個參數都是IEnumerable<T> 類型,表示它能夠經過IEnumerable<T>類型進行調用。spa

淺析數組類型.net

1. 全部數組類型都隱式派生自Array對象

  當咱們定義一個FileStream[] 數組時,CLR會爲當前的AppDomain建立一個FileStream[] 類型,該類型派生自 Array。因此數組是引用類型,在堆中分配內存空間。Array類是一個抽象類,定義了許多關於經常使用的實例方法和靜態方法,供全部的數組類型使用。例如常見的:Length屬性,CopyTo方法等等。blog

2. 全部的數組類型都隱式實現了IEnumerable<T>接口繼承

  就如上面所所的,這是一個理所固然的問題,爲了提升開發效率,數組類型理應可使用linq進行查詢。但因爲數組能夠是多維數組或者非0基數組,因此Array類並無實現IEnumerable<T>、ICollection<T>、IList<T> 這幾個泛型接口,而只是實現了非泛型版本的。實際上,CLR會自動爲一維的數組類型實現這些泛型接口(指定T類型參數的具體類型),而且還會爲它們的父類實現。例如咱們定義一個FileStream[] 數組類型,那麼CLR會爲咱們建立以下的層次類型結構:接口

  

  因爲CLR的隱式實現,才使咱們能夠將一維數組類型應用在須要IEnumerable<T>泛型接口的地方。內存

  按照上面的說法,咱們能夠將FileStream[] 類型的對象傳遞給以下的方法:開發

  void F1(IEnumerable<object> oEnumerable);

  void F2(ICollection<Stream> sCollection);

  void F3(IList<FileStream> fList);

  這是對於引用類型而言的,若是是值類型,則不爲會它的基類實現這些接口。例如DateTimel類型(基類包括ValueType和Object),DateTime[]數組類型不能傳遞給上面的F1方法,這是由於值類型的數組的內存佈局與引用類型的數組不一樣。

相關文章
相關標籤/搜索