as List <>与ToList()之间的区别

时间:2018-08-26 08:30:19

标签: c#

我有一个作为Enumerable的字符串集合(例如,假设它是对集合进行某些linq查询的结果)。

IEnumerable<string> myStrings;

以下内容有什么区别

a。

result = myStrings as List<string>;

b。

result = myStrings.ToList();

一个比另一个更有效吗?选项b是否会更改myStrings本身?

3 个答案:

答案 0 :(得分:2)

选项a-result=myStrings as List<string>是一种安全的类型转换方式,它知道给定类型内部是否包含List<string>,因此没有多余的内存分配,因为它是类型转换,可以在任何类型/对象上完成。如果类型转换失败,则结果为null,没有异常,而如果尝试(List<string>) myStrings,可能会出现异常。

实际上甚至更好的方法-is运算符myStrings is List<string> result(称为模式匹配是表达式),它提供布尔结果,如果为true,则会在结果变量(is中产生有效值运算符已经存在了一段时间,但是使用变量result进行模式匹配,它跨越了if循环,并且可以在其后的逻辑中使用,这是C#7.1的功能

与此相比:

选项b-result=myStrings.ToList()是对IEnumerable<T>的扩展方法调用,它分配并创建新的List<T>数据结构。这始终是额外的内存分配。以下是Enumerable.ToList()调用link

的源代码
 public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
            if (source == null) throw Error.ArgumentNull("source");
            return new List<TSource>(source);
        }

答案 1 :(得分:1)

ToList()是一种方法,它创建List<T>的新对象。该方法要求集合中的元素为正确的类型。

方法ToList遍历集合以创建列表,因此它不仅比强制转换慢,而且更安全,更通用。

由于该方法创建了新列表,因此原始集合的更改不会反映在列表中。

as List<T>将对象投射到该列表上。这意味着集合必须是List或从中继承。

当无法将对象投射在null上时,铸造有时会导致List<T>

由于对象的转换仍保留引用,因此对原始集合的更改将反映在列表中。


更多信息:

ToList()

https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tolist?redirectedfrom=MSDN&view=netframework-4.7.2#System_Linq_Enumerable_ToList__1_System_Collections_Generic_IEnumerable___0__

as

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as

答案 2 :(得分:0)

ToList将创建一个新列表,但对于您而言,由于您引用的是引用类型(字符串),因此新列表将包含对与原始列表相同的对象的引用。

更新新列表中引用的对象的myStrings属性也会影响原始列表中的等效对象。

因此两者之间没有立即差异。

回答您的问题,选项b是否会更改myStrings本身。

关于性能,是的。如本post所述:

  

是的,IEnumerable<T>.ToList()确实会对性能产生影响,   是 O(n)操作,尽管可能只需要关注   性能至关重要的操作。

     

ToList()操作将使用[List(IEnumerable<T> collection)] [2]构造函数。此构造函数必须复制   数组(通常为IEnumerable<T>),否则为将来   原始数组的修改将在源T[]上更改   也是通常不希望的。

这将回答您的第二个问题,即是否会影响性能。