Возвращение фрагментов массива - PullRequest
1 голос
/ 19 декабря 2008

Мне нужно получить фрагменты массива из массива. Я устал от использования Array.Copy (). new ArraySegment (..). Массив возвращает исходный [полный] массив. Ниже приводится то, что я придумал, но я чувствую, что это довольно отстойно. Есть ли лучший способ сделать это?

</p> <pre><code>class Program { static void Main(string[] args) { var arr = new ArraySegment<byte>(new byte[5] { 5, 4, 3, 2, 1 }, 0, 2).ArrayFragment(); for (int i = 0; i < arr.Length; i++) Console.WriteLine(i); Console.Read(); } } static class Extensions { public static T[] ArrayFragment<T>(this ArraySegment<T> segment) { var arr = new T[segment.Count]; Array.Copy(segment.Array, segment.Offset, arr, 0, segment.Count); return arr; } }

Заранее спасибо.

Обновление: Выше был только пример.
У меня есть метод: byte [] CalculateXXX (ключ byte [], сообщение byte []); Я делаю манипуляции с массивами внутри этого метода. Я хочу вернуть часть массива. ArraySegment не реализует IEnumerable и НЕ возвращает массив только с сегментом new ArraySegment (arr ...). Array возвращает полный исходный массив.

</p> <p>var rval = new byte[4]; //new ArraySegment(finalOutputBuffer, 0, 4).SegmentedArray(); Array.Copy(finalOutputBuffer, 0, rval, 0, 4);</p> <p>

Я обнаружил, что должен был сделать выше, чтобы вернуть фрагмент массива. Было просто интересно, есть ли лучший способ вернуть фрагменты массива [как новый массив].

Ответы [ 3 ]

1 голос
/ 19 декабря 2008

Определите лучше. В чем недостаток ArraySegment? Какая проблема у вас, что это не решает?


Редактировать : Хорошо, теперь я понимаю вашу точку зрения, но это неправильно. Это может быть ошибкой в ​​том смысле, что вы чувствуете, что должны делать больше, но они делают именно то, что должны делать. Он позволяет передавать информацию в фрагмент кода о массиве, который вы хотите использовать, и о том, какую часть массива использовать.

Он не предоставляет IEnumerable или что-то, что дает вам узкое представление о массиве, т.е. x [0] не дает вам первый элемент сегмента, и вы не можете рассматривать его как элемент.

Так что да, это довольно бесполезно само по себе, но вы не смогли бы получить что-то, что является массивом в глубине, и все же также является сегментом большего массива.

Вы можете легко создать свой собственный класс, подобный коллекции, который ссылается на массив и использует массив в качестве хранилища, а также обеспечивает индексацию, перечисление и т. Д.

Но это не то, что делает эта структура. Я предполагаю, что главная проблема здесь в том, что они заставили вас ожидать большего от его имени.

1 голос
/ 19 декабря 2008

Vyas, я действительно извините за то, что выложил эту бесполезную кучу ****. Уже давно я использовал ArraySegment, и я просто предположил, что в нем реализован (более или менее) непротиворечивый интерфейс. Кто-то (Джон?), Пожалуйста, скажите мне, какие наркотики использовались во время реализации этой бесполезной структуры.

Наконец, короче говоря, лучшим решением, вероятно, является реализация собственной версии ArraySegment, только делая ее правильно.

Я не понимаю вашей проблемы с использованием ArraySegment. Здесь нет никаких дополнительных затрат, если вы это имеете в виду, поскольку копирование исходных данных не выполняется. Скорее, ArraySegment предлагает упрощенное представление данных.

Чтобы это сработало, измените свой (возвращаемый) тип с T[] на IEnumerable<T> или, если вам нужен индексированный доступ, на IList<T>. Обычно предпочитают использовать типы интерфейсов в сигнатурах методов и полностью избегать типов массивов. Обоснование очень простое: оно устраняет такие проблемы, как ваша, и делает интерфейс более гибким и ориентированным на будущее. Он также обеспечивает лучшее скрытие информации, поскольку скрывает части реализации, которые не имеют отношения к потребителю этого метода.

0 голосов
/ 14 апреля 2009

Еще один побочный эффект плохого дизайна итератора в C #, кстати. Есть много похожих примеров (просто как «lame»), где было бы просто хорошо проектировать, чтобы иметь возможность передавать или указывать или контролировать сегменты (так называемая концепция, называемая range) без всякого арханикализатора. Копировать семантику или нет, массив также четко определенная концепция.

Просто используйте C ++. : -)

...