![](/img/trans.png)
[英]Can I take advantage of List<T> functions Remove(T) and Insert(Int32, T) when using UpdateRange(IEnumerable<T>)?
[英]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.Array
是IEnumerable
。 不僅因為它在引用中,而且因為使用[]
構造函數語法的第一個示例工作正常。
那么這里的問題是什么? 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.