Я только что натолкнулся на этот ArraySegment<byte>
тип при создании подкласса MessageEncoder
.
Теперь я понимаю, что это сегмент данного массива, принимает смещение, не перечислим и не имеет индексатора, но я все еще не понимаю его использования. Может кто-нибудь объяснить на примере?
ArraySegment
это перечислимо в .Net 4.5.Ответы:
ArraySegment<T>
стал намного более полезным в .NET 4.5 + и .NET Core, поскольку теперь он реализует:IList<T>
ICollection<T>
IEnumerable<T>
IEnumerable
IReadOnlyList<T>
IReadOnlyCollection<T>
в отличие от версии .NET 4, в которой вообще не было интерфейсов.
Теперь класс может участвовать в чудесном мире LINQ, поэтому мы можем делать обычные LINQ-вещи, такие как запрос содержимого, обратное изменение содержимого, не затрагивая исходный массив, получение первого элемента и т. Д.
источник
GetEnumerator
частными, то есть вы вынуждены использоватьIEnumerable<T>
(преобразование бокса), чтобы вызвать это. Ух!В этом примере мы рассмотрим, как можно использовать исходный массив, свойства Offset и Count, а также как можно выполнить цикл по элементам, указанным в ArraySegment.
Структура ArraySegment - о чем они думали?
источник
i < segment.Offset + segment.Count
.Это маленькая структура солдатика, которая ничего не делает, кроме как хранит ссылку на массив и хранит диапазон индексов. Немного опасно, имейте в виду, что он не делает копию данных массива и никоим образом не делает массив неизменяемым или не выражает необходимость неизменности. Более типичный шаблон программирования - просто сохранить или передать массив и переменную или параметр длины, как это делается в методах .NET BeginRead (), String.SubString (), Encoding.GetString () и т. Д. И т. Д.
Он не находит особого применения внутри .NET Framework, за исключением того, что кажется одним конкретным программистом Microsoft, который работал над веб-сокетами, и WCF это понравилось. Это, вероятно, правильное руководство, если оно вам нравится, используйте его. В .NET 4.6 он действительно выглянул, добавленный метод MemoryStream.TryGetBuffer () его использует.
out
Я полагаю, что предпочтительнее иметь два аргумента.В общем, более универсальное понятие срезов занимает одно из первых мест в списке желаний главных инженеров .NET, таких как Мадс Торгерсен и Стивен Тауб. Последние
array[:]
некоторое время назад выдвинули предложение по синтаксису, вы можете увидеть, о чем они думали, на этой странице Roslyn . Я предполагаю, что в конечном итоге это зависит от получения поддержки CLR. Это активно обсуждается для C # версии 7 afaik, следите за System.Slices .Обновление: мертвая ссылка, поставляется в версии 7.2 как Span .
Update2: дополнительная поддержка в C # версии 8.0 с типами Range и Index и методом Slice ().
источник
Что насчет класса-оболочки? Просто чтобы не копировать данные во временные буферы.
Пример:
Выход:
источник
IEnumerable<T>
затем добавить IEnumeratorIEnumerable.GetEnumerator() { return GetEnumerator(); }
ArraySegment НАМНОГО полезнее, чем вы думаете. Попробуйте запустить следующий модульный тест и приготовьтесь удивиться!
Видите ли, все, что вам нужно сделать, это преобразовать ArraySegment в IList, и он сделает все то, что вы, вероятно, ожидали от него в первую очередь. Обратите внимание, что типом по-прежнему является ArraySegment, хотя он ведет себя как обычный список.
ВЫВОД:
источник
IList<T>
. Я ожидал, что индексатор будетpublic
.Проще говоря: он хранит ссылку на массив, что позволяет иметь несколько ссылок на одну переменную массива, каждая из которых имеет свой диапазон.
Фактически, это помогает вам использовать и передавать разделы массива более структурированным образом, вместо того, чтобы иметь несколько переменных, для хранения начального индекса и длины. Также он предоставляет интерфейсы коллекций, чтобы упростить работу с разделами массива.
Например, следующие два примера кода делают то же самое, один с ArraySegment, а другой без:
и,
Очевидно, что первый фрагмент кода более предпочтителен, особенно если вы хотите передать сегменты массива функции.
источник