[英]How to simplify the initialization of List<List<Int32>> as IEnumerable<IEnumerable<Int32>>?
我正在做以下集合初始化:
Int32[,] v1 = new Int32[2, 2] { { 1, 2 }, { 3, 4 } };
IEnumerable<IEnumerable<Int32>> v2 = new List<List<Int32>> { { 2, 3 }, { 3, 4 } };
在第二行我得到錯誤:
No overload for method 'Add' takes 2 arguments
有沒有辦法使用最新的 C# 版本來創建IEnumerable<IEnumerable<Int32>>
而不為主集合中的每個項目添加new List<Int32>
?
IEnumerable<IEnumerable<Int32>> v2 = new List<List<Int32>> {
new List<Int32> { 2, 3 },
new List<Int32> { 3, 4 }
};
無需圍繞List<List<T>>
編寫包裝器!
集合初始值設定項只是調用由 object 聲明的Add
方法的語法糖,而List<T>
沒有聲明采用 2 個參數(或 1 個以上的任意數量的參數)的Add
方法。
但是,集合初始值設定項也會調用名為Add
的擴展方法。 這意味着我們可以這樣寫:
public static class ListExtensions
{
public static void Add<T>(this List<List<T>> list, params T[] items)
{
list.Add(new List<T>(items));
}
}
這讓我們可以寫:
IEnumerable<IEnumerable<int>> collection = new List<List<int>>()
{
{ 1, 2 },
{ 3, 4 },
};
值得注意的是,這種Add
方法只能作為擴展方法添加—— List<T>
不可能自己聲明它。 這樣做的原因是只有當列表包含其他列表時才有意義,並且無法定義僅適用於某些類型列表的實例方法。 但是,您可以在擴展方法上添加各種類似的限制。 您可以在List<T>
上編寫擴展方法,該方法僅適用於T
是 class,或者實際上僅適用於T
是另一個列表時!
來自C# Programming Guide 中的 Object 和 Collection Initializers 文章:
集合初始值設定項允許您在初始化實現
IEnumerable
並具有Add
的集合類型時指定一個或多個元素初始值設定項作為實例方法或擴展方法。
因此,這里的問題是List<T>.Add()
沒有適當的重載采用可變數量的 arguments。
如果你定義了一個自定義集合類型,你可以添加一個帶有params
參數的Add()
方法:
class NestedList<T> : IEnumerable<IEnumerable<T>>
{
List<List<T>> _list;
public NestedList()
{
_list = new List<List<T>>();
}
public void Add(params T[] innerItems)
{
_list.Add(new List<T>(innerItems));
}
public IEnumerator<IEnumerable<TI>> GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
現在我們有一個Add()
方法,它接受可變數量的 arguments,您可以使用嵌套初始化程序:
IEnumerable<IEnumerable<int>> v2 = new NestedList<int> { { 1, 2 }, { 3, 4 } };
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.