tolist()仅适用于泛型数组(如string[]、int[]),因其实现ienumerable;非泛型array或object[]需先cast()或oftype()再调用,否则报cs1061或invalidcastexception。

直接用 ToList() 就行,但别无脑调用——它只对实现了 IEnumerable<t></t> 的数组有效,且会创建新对象,原数组修改不影响 List,反之亦然。
为什么 ToArray() 能转回来,但 ToList() 有时报错?
根本原因不是函数本身有问题,而是调用对象类型不对。C# 中只有泛型数组(如 string[]、int[])才默认实现 IEnumerable<t></t>,能直接链式调用 ToList();而非泛型数组(如 Array 类型变量)、或 object[] 里装了不同类型的值,就会触发编译错误或运行时异常。
常见错误现象:
CS1061: 'Array' does not contain a definition for 'ToList'- 运行时报
InvalidCastException,尤其在object[]强转为List<string></string>时
实操建议:
- 确认变量声明类型是
string[]、int[]等具体泛型数组,而非Array或object[] - 如果只有
Array实例,先用Cast<t>()</t>再ToList(),例如:((string[])arr).ToList()或arr.Cast<string>().ToList()</string> - 不确定元素类型时,用
OfType<t>()</t>更安全(自动过滤不匹配的项)
new List<t>(array)</t> 和 array.ToList() 有啥区别?
两者都生成新 List<t></t>,但底层行为和适用场景不同。
关键差异:
-
new List<t>(array)</t>是构造函数直传,性能略优(少一次扩展方法查找 + 内部直接拷贝) -
array.ToList()是 LINQ 扩展方法,依赖System.Linq命名空间,必须引入using System.Linq; - 当
array为null时,new List<t>(array)</t>抛ArgumentNullException;array.ToList()同样抛异常,但错误堆栈更长 - 二者都不改变原数组,都是深拷贝引用、浅拷贝值(即
string[]转成List<string></string>后,修改 List 里的 string 引用不影响数组,但若 string 是可变引用类型则另说)
示例对比:
int[] arr = { 1, 2, 3 };
List<int> list1 = new List<int>(arr); // ✅ 推荐用于已知非 null 场景
List<int> list2 = arr.ToList(); // ✅ 简洁,但需 using System.Linq</int></int></int>
二维数组或 string[][] 怎么转成 List<list>></list>?
C# 数组的维度信息不会自动映射到泛型集合,ToList() 对二维数组(如 int[,] )直接报错,因为它实现的是 IEnumerable 而非 IEnumerable<int></int>。
实操建议:
- 锯齿数组(
string[][])可用Select(x => x.ToList()).ToList(),前提是每个子数组非 null - 矩形二维数组(
int[,])得先拉平或按行/列遍历:Enumerable.Range(0, arr.GetLength(0)).Select(i => Enumerable.Range(0, arr.GetLength(1)).Select(j => arr[i, j]).ToArray()).ToList() - 更稳妥的做法是显式循环,避免 LINQ 嵌套过深导致可读性差或调试困难
容易踩的坑:
- 误把
int[,]当作int[][]处理,结果编译失败或逻辑错乱 - 没检查子数组是否为
null,导致NullReferenceException
最常被忽略的一点:数组转 List 后,如果后续还要频繁查下标、或保证顺序不变,没问题;但如果主要做增删操作,记得 List 的 Insert() 和 RemoveAt() 是 O(n) 操作,大数据量时比不上 LinkedList<t></t> 或索引优化结构。别只盯着“怎么转”,忘了“转完干啥”。











