Подтвердить что ты не робот

Могу ли я полагаться на LINQ ToArray(), всегда возвращающий новый экземпляр?

Я ищу простой способ клонировать параметр IEnumerable<T> для последующей справки. LINQ ToArray метод расширения выглядит как хороший, лаконичный способ сделать это.

Однако я не понимаю, всегда ли гарантированно возвращать новый экземпляр массива. Некоторые из методов LINQ будут проверять фактический тип перечислимого и, если возможно, ярлык; например, Count() увидит, реализует ли метод ICollection<T>, и если да, то будет непосредственно читать свойство Count; он выполняет только итерацию коллекции, если она должна.

Учитывая, что мышление короткого замыкания там, где это практично, кажется, что, если я назову ToArray() на то, что уже является массивом, ToArray() может замыкаться и просто возвращать один и тот же экземпляр массива. Это технически выполнило бы требования метода ToArray.

Из быстрого теста выясняется, что в .NET 4.0 вызов ToArray() в массиве возвращает новый экземпляр. Мой вопрос: Я могу полагаться на это? Можно ли гарантировать, что ToArray всегда будет возвращать новый экземпляр даже в Silverlight и в будущих версиях .NET Framework? Есть ли документация где-то, что ясно в этой точке?

4b9b3361

Ответ 1

Да, ToArray всегда будет возвращать новый массив - заставить его изменить, чтобы возвращать существующее значение, было бы ужасно нарушающим изменением, и я совершенно уверен, что команда .NET этого не сделает. Это важная вещь, на которую можно положиться. Это позор, который не задокументирован: (

В LINQ для объектов есть много тонких бит поведения, которые, вероятно, не стоит полагаться на них, но в этом случае это такой массивный бит поведения, я был бы совершенно удивлен тем, что он изменился.

Короткое замыкание отлично, когда оно не влияет на поведение, но, как правило, LINQ to Objects довольно хорош только для оптимизации в действительных случаях. Вы можете посмотреть два сообщения в моя оптимизация серии Edulinq.

Ответ 2

Так как этот метод ToArray является внутренним для платформы .NET, я бы не стал ставить свою жизнь на MS, не меняя ее. Однако, что бы я сделал, нужно добавить Unit Test, утверждая, что ToArray возвращает новый экземпляр массива.

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

Таким образом, если позже вы измените версии платформы .NET, вы автоматически узнаете, изменились ли функциональные возможности.