OOC:出于好奇
所以,作为一个小练习,为了学习,我决定检查我是否能够实现一个非常基本的递归函数,它将返回List<int>
,但有以下限制:
1-结果应该由函数本身返回(而不是作为参数传递给void
函数)。
2 - 在函数体中没有声明本地“命名”变量。
我想出了下面的解决方案(BTW:这可以以任何方式改进吗?)
在执行此操作时,我了解到ToList()
与投射到List<T>
不同(参见下面的示例) - 任何人都能解释幕后发生的事情以及它们之间的区别这两个是?
谢谢!
PS - 我正在使用4.0版(如果它很重要)。
编辑:运行时错误为Unable to cast object of type '<ConcatIterator>d__71'1[System.Int32]' to type 'System.Collections.Generic.List'1[System.Int32]'
public static List<int> SomeIntegers(int min, int max)
{
//assume max >= min for simplicity
if (min == max)
return new List<int>() { min };
// runtime error
//return (List<int>)(SomeIntegers(min, max - 1).Concat(new List<int>() { max }));
//works
return (SomeIntegers(min, max - 1).Concat(new List<int>() { max })).ToList();
}
答案 0 :(得分:12)
ToList与List(铸造)不同于List。
ToList获取任何IEnumerable(列表,数组,字典,集合等)并将其转换为列表。
Casting to List会获取一个已经是某种列表的对象,并将其标记为列表。例如:
// fail -- arrays are not lists
var not_a_list = (List<int>)int[];
// success: arrays *are* IEnumerable, so you can convert them to a list.
var list_from_array = new [] { 1,2,3,4,5 }.ToList();
// success: WorkflowRoleCollection derives from List<WorkflowRole>
var derived_from_list = (List<WorkflowRole>) new WorkflowRoleCollection();
在您的情况下,Concat返回IEnumerable,而不是List。请记住,它必须支持生成器(它们是惰性评估的),所以它就像下面的列表一样没有意义。
顺便问一下,你看过内置函数Enumerable.Range
吗?
答案 1 :(得分:3)
List<T>
,某些内容来自List<T>
或某种类型转换为List<T>
的内容时,>转换才有效,否则会失败并显示InvalidCastException
。 ToList()
适用于任何IEnumerable。ToList()
也会始终创建列表的新副本。将某些内容转换为List<T>
通常不会生成列表的副本 - 它只为您提供了同一对象的新编译时类型。答案 2 :(得分:2)
顺便说一句,生成整数列表的最佳方法是:
Enumerable.Range(min, length);
或
Enumerable.Range(min, max-min+1);
但这对你学习没有帮助,所以对你有所帮助! :)