为什么 List.AddRange 接受 T[] 但不接受 IEnumerable<T>
Why does List.AddRange accept T[] but doesn't accept IEnumerable<T>
所以我试图稍微重构我的代码,我需要一种方法来检查数组是否为 null,然后如果不为空,则将该数组中的项目添加到列表中。我需要将许多继承自相同 class 的不同项目添加到 class.
的列表中
我写了这个方法:
private void AddItems<T>(T[] items) where T : SomeClass
{
if (items != null)
{
someList.AddRange(items);
}
}
这很好用,但我的问题是为什么会这样:
private void AddItems<T>(IEnumerable<T> items) where T : SomeClass
{
if (items != null)
{
someList.AddRange(items);
}
}
不工作?
The latter example produces this error: "Argument 1: cannot convert from System.Collections.Generic.IEnumerable<T>
to System.Collections.Generic.IEnumerable<SomeClass>
"
List<SomeClass> someList = new List<SomeClass>();
error
这与数组和泛型的工作方式有关。您有一个这样键入的变量:
IEnumerable<SomeSpecificClass>
你知道 SomeSpecificClass
总是继承自 SomeClass
。您想要使用 AddRange()
将该序列中的所有项目添加到 List<SomeClass>
。但是 List<SomeClass>.AddRange
是特定的;它正好需要一个 IEnumerable<SomeCass>
,你不能直接从 IEnumerable<SomeSpecificClass>
转换为 IEnumerable<SomeClass>
。你可以用一个简单的 Cast<T>()
:
来解决这个问题
someList.AddRange(items.Cast<SomeClass>());
现在的问题是数组为什么起作用,答案是数组在这方面很特殊。它们不仅仅是仿制药。您可以直接将 SomeSpecificClass[]
转换为 SomeClass[]
,并且由于 SomeClass[]
实现了 IEnumerable<SomeClass>
,所以一切都很好。
所以我试图稍微重构我的代码,我需要一种方法来检查数组是否为 null,然后如果不为空,则将该数组中的项目添加到列表中。我需要将许多继承自相同 class 的不同项目添加到 class.
的列表中我写了这个方法:
private void AddItems<T>(T[] items) where T : SomeClass
{
if (items != null)
{
someList.AddRange(items);
}
}
这很好用,但我的问题是为什么会这样:
private void AddItems<T>(IEnumerable<T> items) where T : SomeClass
{
if (items != null)
{
someList.AddRange(items);
}
}
不工作?
The latter example produces this error: "Argument 1: cannot convert from
System.Collections.Generic.IEnumerable<T>
toSystem.Collections.Generic.IEnumerable<SomeClass>
"
List<SomeClass> someList = new List<SomeClass>();
error
这与数组和泛型的工作方式有关。您有一个这样键入的变量:
IEnumerable<SomeSpecificClass>
你知道 SomeSpecificClass
总是继承自 SomeClass
。您想要使用 AddRange()
将该序列中的所有项目添加到 List<SomeClass>
。但是 List<SomeClass>.AddRange
是特定的;它正好需要一个 IEnumerable<SomeCass>
,你不能直接从 IEnumerable<SomeSpecificClass>
转换为 IEnumerable<SomeClass>
。你可以用一个简单的 Cast<T>()
:
someList.AddRange(items.Cast<SomeClass>());
现在的问题是数组为什么起作用,答案是数组在这方面很特殊。它们不仅仅是仿制药。您可以直接将 SomeSpecificClass[]
转换为 SomeClass[]
,并且由于 SomeClass[]
实现了 IEnumerable<SomeClass>
,所以一切都很好。