23

我正在寻找一种简单的方法来克隆IEnumerable<T>参数以供以后参考。LINQ 的ToArray扩展方法似乎是一种很好、简洁的方法。

但是,我不清楚它是否总是保证返回一个新的数组实例。一些 LINQ 方法将检查可枚举的实际类型,如果可能,还可以使用快捷方式;例如,Count()将查看该方法是否实现ICollection<T>,如果是,将直接读取其Count属性;它只在必要时迭代集合。

考虑到实际可行的短路思维,如果我调用已经数组ToArray()的东西,似乎可能会短路并简单地返回相同的数组实例。从技术上讲,这将满足方法的要求。ToArray()ToArray

从快速测试中可以看出,在 .NET 4.0 中,调用ToArray()数组确实会返回一个新实例。我的问题是,我可以依靠这个吗?即使在 Silverlight 和 .NET Framework 的未来版本中,我能否保证ToArray始终返回一个新实例?在这一点上是否有明确的文档?

4

2 回答 2

26

是的,ToArray将始终返回一个新数组 - 将其更改为返回现有值将是一个可怕的破坏性更改,我完全相信 .NET 团队不会这样做。能够依靠是一件很重要的事情。很遗憾它没有记录在案:(

LINQ to Objects 中有许多微妙的行为可能不值得依赖,但在这种情况下,它的行为如此庞大,我绝对会惊讶于它的改变。

短路在不影响行为时非常有用,但通常 LINQ to Objects 仅在有效情况下进行优化非常好。您可能想查看我的 Edulinq 系列中关于优化的两篇 文章

于 2011-05-20T15:38:36.587 回答
16

由于 ToArray 方法是 .NET 框架的内部方法,因此我不会将我的生命押在 MS 上,永远不会改变它。但是,我要做的是添加一个单元测试,断言 ToArray 返回一个新的数组实例。

Assert.AreNotSame(myArray, myArray.ToArray());

这样,如果您稍后更改 .NET 框架版本,您将自动知道功能是否更改。

于 2011-05-20T15:40:31.357 回答