Acabei de encontrar o ArraySegment<byte>
tipo enquanto fazia a subclasse da MessageEncoder
classe.
Agora entendo que é um segmento de uma determinada matriz, tem um deslocamento, não é enumerável e não tem um indexador, mas ainda não consigo entender seu uso. Alguém pode explicar com um exemplo?
ArraySegment
é enumerável em .Net 4.5.Respostas:
ArraySegment<T>
tornou-se muito mais útil no .NET 4.5 + e .NET Core , pois agora implementa:IList<T>
ICollection<T>
IEnumerable<T>
IEnumerable
IReadOnlyList<T>
IReadOnlyCollection<T>
ao contrário da versão .NET 4, que não implementou nenhuma interface.
A classe agora é capaz de participar do maravilhoso mundo do LINQ para que possamos fazer as coisas normais do LINQ, como consultar o conteúdo, reverter o conteúdo sem afetar a matriz original, obter o primeiro item e assim por diante:
fonte
GetEnumerator
privado, significando que você é forçado a lançar paraIEnumerable<T>
(uma conversão de boxe) para convocar. Ugh!Neste exemplo, veremos como você pode usar o array original, as propriedades Offset e Count, e também como você pode percorrer os elementos especificados no ArraySegment.
Estrutura ArraySegment - o que eles estavam pensando?
fonte
i < segment.Offset + segment.Count
.É uma pequena estrutura de soldado insignificante que não faz nada além de manter uma referência a uma matriz e armazena um intervalo de índice. Um pouco perigoso, tome cuidado para que isso não faça uma cópia dos dados do array e não torne o array imutável ou expresse a necessidade de imutabilidade. O padrão de programação mais típico é apenas manter ou passar a matriz e uma variável de comprimento ou parâmetro, como é feito nos métodos .NET BeginRead (), String.SubString (), Encoding.GetString (), etc, etc.
Não é muito usado dentro do .NET Framework, exceto pelo que parece ser um programador específico da Microsoft que trabalhava em sockets da Web e gostava do WCF. O que é provavelmente a orientação adequada, se você gostar, use-a. Ele fez um peek-a-boo no .NET 4.6, o método adicionado MemoryStream.TryGetBuffer () o usa. Preferido a ter dois
out
argumentos, presumo.Em geral, a noção mais universal de fatias está no topo da lista de desejos dos principais engenheiros do .NET, como Mads Torgersen e Stephen Toub. Este último deu início à
array[:]
proposta de sintaxe há um tempo, você pode ver o que eles estão pensando nesta página de Roslyn . Eu presumo que obter suporte CLR é o que depende em última análise. Isso está sendo pensado ativamente para o C # versão 7 afaik, fique de olho no System.Slices .Atualização: link morto, enviado na versão 7.2 como Span .
Update2: mais suporte no C # versão 8.0 com os tipos Range e Index e um método Slice ().
fonte
Que tal uma classe wrapper? Apenas para evitar copiar dados para buffers temporais.
Exemplo:
Ouput:
fonte
IEnumerable<T>
e adicionar IEnumeratorIEnumerable.GetEnumerator() { return GetEnumerator(); }
O ArraySegment é MUITO mais útil do que você imagina. Tente executar o seguinte teste de unidade e prepare-se para se surpreender!
Veja, tudo o que você precisa fazer é lançar um ArraySegment para IList e ele fará todas as coisas que você provavelmente esperava que fizesse em primeiro lugar. Observe que o tipo ainda é ArraySegment, embora esteja se comportando como uma lista normal.
RESULTADO:
fonte
IList<T>
. Eu esperaria que o indexador fossepublic
.Em palavras simples: ele mantém referência a um array, permitindo que você tenha várias referências a uma única variável de array, cada uma com um intervalo diferente.
Na verdade, ajuda você a usar e passar seções de um array de uma forma mais estruturada, em vez de ter várias variáveis, para manter o índice inicial e o comprimento. Também fornece interfaces de coleção para trabalhar mais facilmente com seções de array.
Por exemplo, os dois exemplos de código a seguir fazem a mesma coisa, um com ArraySegment e outro sem:
e,
Obviamente, o primeiro fragmento de código é mais preferido, especialmente quando você deseja passar segmentos de array para uma função.
fonte