2013-09-25 31 views
0

我有一些使用反向扩展方法的代码。.NET ToList是否保证始终返回一个新对象?

为了确保它不会颠倒原始列表,原始程序员使用GetRange创建了一个新列表。

dim a = New List(of Thing) 
... fill in a 
dim b = a.GetRange(0, a.count) 
b.reverse() 

推测GetRange保证始终创建一个新的对象。这是否也适用于ToList?

然后,我可以写:

dim a = New List(of Thing) 
... fill in a 
dim b = a.ToList() 
b.reverse() 

的优点则是一个类型可以是IEnumerable的(的T),它仍然能工作。

我自己测试过这一点,它一直是真实的,b是一个新的对象。问题是这样的:

是否保证未来的实现会表现相同或者这种行为是否是实现中的事故?

一个明显的'优化'将返回对原始对象的引用,如果它已经是一个列表,这当然意味着第二个版本会颠倒原始列表。

+0

相关:[?ToList() - 它创建一个新的列表]( http://stackoverflow.com/q/2774099/1149773) – Douglas

回答

1

基于此source,我会假设它确实如此,但如果msdn文章中提到的查询是空的,那么它只会返回一个空列表。

鉴于您没有设法反驳这一点,您可能需要对此进行进一步的研究才能找到真正的答案。

1

我不明白这只是一个实现细节。

IEnumerable<T>并不一定是一个列表。只是可以枚举的东西。所以ToList()没有别的选择,只能遍历整个枚举并创建一个包含所有结果的新列表。

我能想到的唯一警告是如果他们在ToList里面专门检查输入的类型是List<T>并且只是返回一个对它的引用。

但是,这将破坏现有的代码,它永远不会发生。

+0

一些IEnumerable方法肯定是类型检查。 – argaz

+0

@argaz - 的确如同“Count()”一样。但是这样做会检查'ToList()',以便在某些情况下它会创建一个副本,而在其他情况下,参考不会发生。只要他们不能为所有枚举类型创建一个引用(他们不能),他们就无法为其中的任何枚举创建引用。 –

+0

通常情况下,ToX()会创建一个新的引用,而AsX()会返回一个现有的引用(如果存在的话),并创建一个新引用,如果不存在引用。 (https://jira.codehaus.org/browse/GROOVY-1133) – nicodemus13

1

从它的documentation

从IEnumerable

这意味着一个新的实例创建一个列表。

您可一定要创建一个使用一个新的列表:

dim b =New List(Of T)(input) 其中input是一个IEnumerable(Of T)已

+0

感谢提醒我可以明确地调用构造函数。这确实会保证一个新的例子。 –