OOC:ToList()和.NET中的List <t>之间的区别是什么?</t>

时间:2010-01-21 05:23:08

标签: c# collections casting

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(); 
}

3 个答案:

答案 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>的内容时,转换才有效,否则会失败并显示InvalidCastExceptionToList()适用于任何IEnumerable。
  • 即使您已有列表,
  • ToList()也会始终创建列表的新副本。将某些内容转换为List<T>通常不会生成列表的副本 - 它只为您提供了同一对象的新编译时类型。

答案 2 :(得分:2)

顺便说一句,生成整数列表的最佳方法是:

Enumerable.Range(min, length);

Enumerable.Range(min, max-min+1);

但这对你学习没有帮助,所以对你有所帮助! :)