2016-11-18 6 views
2

Я работаю над несколькими методами расширения, где мне нужно преобразовать входную коллекцию в массив. Я хочу сохранить память, поэтому я хочу только создать копию ввода, если это абсолютно необходимо.Вызывается ли вызов .toArray() на ICollection, который является массивом, возвращает ссылку или копию?

Должен ли я сделать:

public static ICollection<TSource> ExtMethod<TSource>(this ICollection<TSource> source, Func<TSource, int> predicate) 
    { 
     TSource[] converted; 
     if (source is TSource[]) 
     { 
      converted = source as TSource[]; 
     } 
     else { 
      converted = source.ToArray(); 
     } 

    } 

Или ToArray сделать проверку под капотом и у меня точно такой же эффект, если я:

public static ICollection<TSource> ExtMethod<TSource>(this ICollection<TSource> source, Func<TSource, int> predicate) 
    { 
     TSource[] converted = source.ToArray(); 
    } 
+2

Непросто проверить? – Itay

+1

Вот источник: https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,783a052330e7d48d,references Нажмите «Буфер» и «ToArray», чтобы узнать, что происходит в конструкторе и на последний ToArray, чтобы посмотреть, что там происходит. –

ответ

4

ToArrayвсегда создает копия. Ваш метод расширения не ведет себя одинаково.

Обратите внимание, что здесь есть и тонкости вокруг типов. Рассмотрим этот код:

string[] x = { "a", "b" }; 
object[] y = x.ExtMethod<object>(); 
object[] z = x.ToArray<object>(); 

Теперь тип исполнения, время y является string[], потому что он вернулся исходный массив - но тип исполнения, время z является object[], потому что он создал новый массив с типом заданного аргумента.