簡體   English   中英

名單 <T> 構造函數(IEnumerable <T> )不接受從Array.CreateInstance(Type,Int32)創建的數組

[英]List<T> Constructor (IEnumerable<T>) doesn't accept an array created from Array.CreateInstance(Type, Int32)

我是編程和.net的新手,我很難理解為什么使用List<T>(IEnumerable<T>)構造函數接受使用[]創建的數組,但不接受使用Array.CreateInstance(Type, Int32)創建的Array.CreateInstance(Type, Int32)

這是有效的:

DirectoryInfo[] dirsArray = foo.GetDirectories();
List<DirectoryInfo> dirsList = new List<DirectoryInfo>(dirsArray);

這不是:

 Array dirsArray = Array.CreateInstance(typeof(DirectoryInfo), 10); //assume we know 10 is the required length
 List<DirectoryInfo> dirsList = new List<DirectoryInfo>(dirsArray);

以上給出了以下編譯器錯誤:

Error   1   The best overloaded method match for 'System.Collections.Generic.List<System.IO.DirectoryInfo>.List(System.Collections.Generic.IEnumerable<System.IO.DirectoryInfo>)' has some invalid arguments

Error   2   Argument 1: cannot convert from 'System.Array' to 'System.Collections.Generic.IEnumerable<System.IO.DirectoryInfo>'

但我知道List<T>(IEnumerable<T>)可以接受任何IEnumerable作為參數。 我知道System.ArrayIEnumerable 不僅因為它在引用中,而且因為使用[]構造函數語法的第一個示例工作正常。

那么這里的問題是什么? Array.CreateInstance以某種方式設法創建一個不是IEnumerable的數組嗎?

Array類本身不是IEnumerable<T> 。你需要轉換Array.CreateInstance結果

var dirsArray = (DirectoryInfo[]) Array.CreateInstance(typeof(DirectoryInfo), 10);

Array是所有數組類型的基類, IEnumerable<T>的實現是在運行時提供的。因此,在編譯時無法使用數組作為IEnumerable<T> 。從MSDN

從.NET Framework 2.0開始,Array類實現System.Collections.Generic.IList<T>System.Collections.Generic.ICollection<T>System.Collections.Generic.IEnumerable<T>泛型接口。 這些實現在運行時提供給數組,因此,泛型接口不會出現在Array類的聲明語法中。

因為Array.CreateInstance(Type, Int32)不返回IEnumerable<T>實例,所以它返回一個Array對象。 如果使用[]創建數組,則它將是IEnumerable<T>

請看一下這個帖子,它很明確: 為什么Array不是泛型類型?

Array.CreateInstance返回一個無類型數組 ,正如您將注意到的那樣,它不實現IEnumerable<T> (它不是通用的),因此不能與List<T>構造函數一起使用。

但是,對於Array.CreateInstance實際返回的Array.CreateInstance是鍵入的,您只需將其轉換為所需的類型(所有類型的數組都是從基類Array派生的)。 所以你可以這樣做:

List<DirectoryInfo> dirsList = new List<DirectoryInfo>((DirectoryInfo[])dirsArray);

它應該編譯。

也就是說,我從來沒有找到使用Array.CreateInstance的理由。

更新 :因為在對原始問題的注釋中,您談到將ControlCollection轉換為List<Control> ,應該注意您不能將ControlCollection轉換為類型化數組。 所以像這樣的東西不起作用:

var lst = (Control[])myControlCollection;

因為ControlCollection (以及框架中的許多舊的,預先泛型,集合)不是從Array派生的。 在這種情況下,由於ControlCollection實現了IEnumerable ,您可以使用Cast擴展方法:

var lst = new List<Control>(myControlCollection.Cast<Control>());

如果它們實現IEnumerable你可以在框架中使用這個技巧和很多集合類。 MatchCollection給出另一個例子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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