Я читал блог Эрика Липперта, где объяснил, почему он почти никогда не будет использовать массивы, и следующая часть меня заинтересовала:
Если вы пишете такой API, оберните массив в ReadOnlyCollection и вернете IEnumerable или IList или что-то еще, но не массив. (И, конечно же, не просто бросайте массив в IEnumerable и думайте, что вы сделали! Это все равно передаёт переменные, вызывающий может просто отбрасывать массив! Только передать массив, если он завернут с помощью объекта только для чтения.)
Итак, я немного потрудился с коллекциями:
string[] array = new[] { "cat", "dog", "parrot" };
IEnumerable<string> test1 = array.AsEnumerable();
string[] secondArray = (string[])test1;
//array1[0] is now also "whale"
array[0] = "whale";
//11 interfaces
var iArray = array.GetType().GetInterfaces();
//Still 11 interfaces??
var iTest1 = test1.GetType().GetInterfaces();
Я инициализирую массив, а затем использую метод AsEnumerable()
на нем, чтобы преобразовать его в IEnumerable
(или так я думал), но когда я вернул его в новый массив и изменил значение в оригинале массив, значения test1
и secondArray
были изменены. По-видимому, я просто сделал две новые ссылки на исходный массив, вместо создания нового IEnumerable
, немного похожего на ToArray()
, возвращает новый массив.
Когда я сравниваю интерфейсы массива и IEnumerable
, они оба имеют одинаковые интерфейсы. Почему массив имеет этот метод, если он вообще ничего не делает? Я знаю, что AsEnumerable()
использует его с Linq-to-entity для получения перечислимых методов, когда у вас есть IQueryable
, но почему этот метод должен быть добавлен в массив? Существует ли практическое применение этого метода?
Изменить: Этот комментарий Тима Шмельтера поднимает действительно хороший момент и не должен оставаться незамеченным:
"Это не так бесполезно. Вы можете изменить фактический тип, не нарушая остальную часть кода. Таким образом, вы можете заменить массив запросом или списком или хешетом базы данных, но AsEnumerable всегда работает, а остальные код тоже. Таким образом, AsEnumerable похож на контракт.