Span<T> Estrutura
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Fornece uma representação segura para tipos e memória de uma região contígua de memória arbitrária.
generic <typename T>
public value class Span
[System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))]
public readonly ref struct Span<T>
public readonly ref struct Span<T>
[<System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))>]
type Span<'T> = struct
type Span<'T> = struct
Public Structure Span(Of T)
Parâmetros de Tipo Genérico
- T
O tipo de itens no Span<T>.
- Herança
- Atributos
Observações
O Span<T> tipo é um ref struct alocado na pilha em vez de no heap gerenciado. Os tipos de ref struct têm algumas restrições para garantir que não podem ser promovidos ao heap gerido, incluindo que não podem ser:
- Encaixado.
- Atribuído a variáveis do tipo Object ou
dynamic, ou a qualquer tipo de interface. - Campos num tipo de referência.
- Usado através
awaitde fronteirasyield.
Além disso, chamadas para dois métodos, Equals(Object) e GetHashCode, lançam um NotSupportedException.
Importante
Por ser um tipo somente de pilha, Span<T> não é adequado para muitos cenários que exigem o armazenamento de referências a buffers no heap. Isso é verdade, por exemplo, para rotinas que fazem chamadas de método assíncronas. Para esses cenários, pode-se usar os tipos System.Memory<T> e System.ReadOnlyMemory<T> complementares.
Para intervalos que representam estruturas imutáveis ou apenas de leitura, use System.ReadOnlySpan<T>.
Memory
A Span<T> representa uma região contígua de memória arbitrária. Uma Span<T> instância é frequentemente usada para armazenar os elementos de uma matriz ou de uma parte de uma matriz. Ao contrário de uma matriz, no entanto, uma instância Span<T> pode referir-se a memória gerida, memória nativa ou memória gerida na pilha. O exemplo a seguir cria um Span<Byte> a partir de uma matriz:
// Create a span over an array.
var array = new byte[100];
var arraySpan = new Span<byte>(array);
byte data = 0;
for (int ctr = 0; ctr < arraySpan.Length; ctr++)
arraySpan[ctr] = data++;
int arraySum = 0;
foreach (var value in array)
arraySum += value;
Console.WriteLine($"The sum is {arraySum}");
// Output: The sum is 4950
// Create a span over an array.
let array = Array.zeroCreate<byte> 100
let arraySpan = Span<byte> array
let mutable data = 0uy
for i = 0 to arraySpan.Length - 1 do
arraySpan[i] <- data
data <- data + 1uy
let mutable arraySum = 0
for value in array do
arraySum <- arraySum + int value
printfn $"The sum is {arraySum}"
// Output: The sum is 4950
O exemplo a seguir cria um Span<Byte> a partir de 100 bytes de memória nativa:
// Create a span from native memory.
var native = Marshal.AllocHGlobal(100);
Span<byte> nativeSpan;
unsafe
{
nativeSpan = new Span<byte>(native.ToPointer(), 100);
}
byte data = 0;
for (int ctr = 0; ctr < nativeSpan.Length; ctr++)
nativeSpan[ctr] = data++;
int nativeSum = 0;
foreach (var value in nativeSpan)
nativeSum += value;
Console.WriteLine($"The sum is {nativeSum}");
Marshal.FreeHGlobal(native);
// Output: The sum is 4950
// Create a span from native memory.
let native = Marshal.AllocHGlobal 100
let nativeSpan = Span<byte>(native.ToPointer(), 100)
let mutable data = 0uy
for i = 0 to nativeSpan.Length - 1 do
nativeSpan[i] <- data
data <- data + 1uy
let mutable nativeSum = 0
for value in nativeSpan do
nativeSum <- nativeSum + int value
printfn $"The sum is {nativeSum}"
Marshal.FreeHGlobal native
// Output: The sum is 4950
O exemplo a seguir usa a palavra-chave stackalloc do C# para alocar 100 bytes de memória na pilha:
// Create a span on the stack.
byte data = 0;
Span<byte> stackSpan = stackalloc byte[100];
for (int ctr = 0; ctr < stackSpan.Length; ctr++)
stackSpan[ctr] = data++;
int stackSum = 0;
foreach (var value in stackSpan)
stackSum += value;
Console.WriteLine($"The sum is {stackSum}");
// Output: The sum is 4950
// Create a span on the stack.
let mutable data = 0uy
let stackSpan =
let p = NativeInterop.NativePtr.stackalloc<byte> 100 |> NativeInterop.NativePtr.toVoidPtr
Span<byte>(p, 100)
for i = 0 to stackSpan.Length - 1 do
stackSpan[i] <- data
data <- data + 1uy
let mutable stackSum = 0
for value in stackSpan do
stackSum <- stackSum + int value
printfn $"The sum is {stackSum}"
// Output: The sum is 4950
Como Span<T> é uma abstração sobre um bloco arbitrário de memória, métodos Span<T> do tipo e métodos com Span<T> parâmetros operam em qualquer Span<T> objeto, independentemente do tipo de memória que ele encapsula. Por exemplo, cada uma das seções separadas do código que inicializam a extensão e calculam a soma de seus elementos pode ser refatorada em métodos únicos de inicialização e cálculo, como ilustra o exemplo a seguir:
public static void WorkWithSpans()
{
// Create a span over an array.
var array = new byte[100];
var arraySpan = new Span<byte>(array);
InitializeSpan(arraySpan);
Console.WriteLine($"The sum is {ComputeSum(arraySpan):N0}");
// Create an array from native memory.
var native = Marshal.AllocHGlobal(100);
Span<byte> nativeSpan;
unsafe
{
nativeSpan = new Span<byte>(native.ToPointer(), 100);
}
InitializeSpan(nativeSpan);
Console.WriteLine($"The sum is {ComputeSum(nativeSpan):N0}");
Marshal.FreeHGlobal(native);
// Create a span on the stack.
Span<byte> stackSpan = stackalloc byte[100];
InitializeSpan(stackSpan);
Console.WriteLine($"The sum is {ComputeSum(stackSpan):N0}");
}
public static void InitializeSpan(Span<byte> span)
{
byte value = 0;
for (int ctr = 0; ctr < span.Length; ctr++)
span[ctr] = value++;
}
public static int ComputeSum(Span<byte> span)
{
int sum = 0;
foreach (var value in span)
sum += value;
return sum;
}
// The example displays the following output:
// The sum is 4,950
// The sum is 4,950
// The sum is 4,950
open System
open System.Runtime.InteropServices
open FSharp.NativeInterop
// Package FSharp.NativeInterop.NativePtr.stackalloc for reuse.
let inline stackalloc<'a when 'a: unmanaged> length : Span<'a> =
let voidPointer = NativePtr.stackalloc<'a> length |> NativePtr.toVoidPtr
Span<'a>(voidPointer, length)
let initializeSpan (span: Span<byte>) =
let mutable value = 0uy
for i = 0 to span.Length - 1 do
span[i] <- value
value <- value + 1uy
let computeSum (span: Span<byte>) =
let mutable sum = 0
for value in span do
sum <- sum + int value
sum
let workWithSpans () =
// Create a span over an array.
let array = Array.zeroCreate<byte> 100
let arraySpan = Span<byte> array
initializeSpan arraySpan
printfn $"The sum is {computeSum arraySpan:N0}"
// Create an array from native memory.
let native = Marshal.AllocHGlobal 100
let nativeSpan = Span<byte>(native.ToPointer(), 100)
initializeSpan nativeSpan
printfn $"The sum is {computeSum nativeSpan:N0}"
Marshal.FreeHGlobal native
// Create a span on the stack.
let stackSpan = stackalloc 100
initializeSpan stackSpan
printfn $"The sum is {computeSum stackSpan:N0}"
// The example displays the following output:
// The sum is 4,950
// The sum is 4,950
// The sum is 4,950
Matrizes
Quando ele encapsula uma matriz, Span<T> pode envolver uma matriz inteira, como fez nos exemplos na seção Memória . Como ele suporta fatiamento, Span<T> também pode apontar para qualquer intervalo contíguo dentro da matriz.
O exemplo a seguir cria uma fatia dos cinco elementos do meio de uma matriz inteira de 10 elementos. Observe que o código dobra os valores de cada inteiro na fatia. Como mostra a saída, as alterações feitas pelo span são refletidas nos valores da matriz.
using System;
var array = new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
var slice = new Span<int>(array, 2, 5);
for (int ctr = 0; ctr < slice.Length; ctr++)
slice[ctr] *= 2;
// Examine the original array values.
foreach (var value in array)
Console.Write($"{value} ");
Console.WriteLine();
// The example displays the following output:
// 2 4 12 16 20 24 28 16 18 20
module Program
open System
[<EntryPoint>]
let main _ =
let array = [| 2; 4; 6; 8; 10; 12; 14; 16; 18; 20 |]
let slice = Span<int>(array, 2, 5)
for i = 0 to slice.Length - 1 do
slice[i] <- slice[i] * 2
// Examine the original array values.
for value in array do
printf $"{value} "
printfn ""
0
// The example displays the following output:
// 2 4 12 16 20 24 28 16 18 20
Segmentações
Span<T> Inclui duas sobrecargas do método Slice que formam uma fatia da extensão atual que começa num índice especificado. Isso torna possível tratar os dados em um Span<T> como um conjunto de blocos lógicos que podem ser processados conforme necessário por partes de um pipeline de processamento de dados com impacto mínimo no desempenho. Por exemplo, como os protocolos de servidor modernos geralmente são baseados em texto, a manipulação de strings e substrings é particularmente importante. Na classe String, o método principal para extrair substrings é Substring. Para pipelines de dados que dependem de manipulação extensiva de strings, o seu uso pode ter algum impacto no desempenho, uma vez que:
- Cria uma nova cadeia de caracteres para armazenar a substring.
- Copia um subconjunto dos caracteres da cadeia de caracteres original para a nova cadeia de caracteres.
Essa operação de alocação e cópia pode ser eliminada usando um Span<T> ou ReadOnlySpan<T>, como mostra o exemplo a seguir:
using System;
class Program2
{
static void Run()
{
string contentLength = "Content-Length: 132";
var length = GetContentLength(contentLength.ToCharArray());
Console.WriteLine($"Content length: {length}");
}
private static int GetContentLength(ReadOnlySpan<char> span)
{
var slice = span.Slice(16);
return int.Parse(slice);
}
}
// Output:
// Content length: 132
module Program2
open System
let getContentLength (span: ReadOnlySpan<char>) =
let slice = span.Slice 16
Int32.Parse slice
let contentLength = "Content-Length: 132"
let length = getContentLength (contentLength.ToCharArray())
printfn $"Content length: {length}"
// Output:
// Content length: 132
Construtores
| Name | Descrição |
|---|---|
| Span<T>(T) |
Cria um novo Span<T> de comprimento 1 em torno da referência especificada. |
| Span<T>(T[], Int32, Int32) |
Cria um novo Span<T> objeto que inclui um número especificado de elementos de um array a partir de um índice especificado. |
| Span<T>(T[]) |
Cria um novo Span<T> objeto sobre a totalidade de um array especificado. |
| Span<T>(Void*, Int32) |
Cria um novo Span<T> objeto a partir de um número especificado de |
Propriedades
| Name | Descrição |
|---|---|
| Empty |
Devolve um objeto vazio Span<T> . |
| IsEmpty |
Devolve um valor que indica se a corrente Span<T> está vazia. |
| Item[Int32] |
Obtém o elemento no índice zero especificado. |
| Length |
Devolve o comprimento do vão atual. |
Métodos
| Name | Descrição |
|---|---|
| Clear() |
Limpa o conteúdo deste Span<T> objeto. |
| CopyTo(Span<T>) | |
| Equals(Object) |
Obsoleto.
Obsoleto.
Chamadas a este método não são suportadas. |
| Fill(T) |
Preenche os elementos deste intervalo com um valor especificado. |
| GetEnumerator() |
Devolve um enumerador para este Span<T>. |
| GetHashCode() |
Obsoleto.
Lança um NotSupportedException. |
| GetPinnableReference() |
Devolve uma referência a um objeto do tipo T que pode ser usado para fixação. Este método destina-se a suportar compiladores .NET e não deve ser chamado por código de utilizador. |
| Slice(Int32, Int32) |
Forma uma fatia a partir do vão atual começando num índice especificado para um comprimento especificado. |
| Slice(Int32) |
Forma uma fatia do vão atual que começa num índice especificado. |
| ToArray() |
Copia o conteúdo deste intervalo numa nova matriz. |
| ToString() |
Devolve a representação da cadeia deste Span<T> objeto. |
| TryCopyTo(Span<T>) |
Tenta copiar a corrente Span<T> para um destino Span<T> e devolve um valor que indica se a operação de cópia foi bem-sucedida. |
Operadores
| Name | Descrição |
|---|---|
| Equality(Span<T>, Span<T>) |
Devolve um valor que indica se dois Span<T> objetos são iguais. |
| Implicit(ArraySegment<T> to Span<T>) |
Define uma conversão implícita de um ArraySegment<T> para um Span<T>. |
| Implicit(Span<T> to ReadOnlySpan<T>) |
Define uma conversão implícita de a Span<T> para um ReadOnlySpan<T>. |
| Implicit(T[] to Span<T>) |
Define uma conversão implícita de um array para um Span<T>. |
| Inequality(Span<T>, Span<T>) |
Devolve um valor que indica se dois Span<T> objetos não são iguais. |
Métodos da Extensão
| Name | Descrição |
|---|---|
| BinarySearch<T,TComparable>(Span<T>, TComparable) |
Pesquisa um valor inteiro ordenado Span<T> usando o tipo genérico especificado |
| BinarySearch<T,TComparer>(Span<T>, T, TComparer) |
Pesquisa numa ordenação Span<T> inteira por um valor especificado usando o tipo genérico especificado |
| BinarySearch<T>(Span<T>, IComparable<T>) |
Pesquisa um valor inteiro ordenado Span<T> usando a interface genérica especificada IComparable<T> . |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
Encontra o comprimento de qualquer prefixo comum partilhado entre |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>) |
Encontra o comprimento de qualquer prefixo comum partilhado entre |
| Contains<T>(Span<T>, T) |
Indica se um valor especificado é encontrado num intervalo. |
| ContainsAny<T>(Span<T>, ReadOnlySpan<T>) |
Procura uma ocorrência de qualquer um dos especificados |
| ContainsAny<T>(Span<T>, SearchValues<T>) |
Procura uma ocorrência de qualquer um dos especificados |
| ContainsAny<T>(Span<T>, T, T, T) |
Procura uma ocorrência de |
| ContainsAny<T>(Span<T>, T, T) |
Procura uma ocorrência de |
| ContainsAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Pesquisa no intervalo especificado qualquer valor que não seja o especificado |
| ContainsAnyExcept<T>(Span<T>, SearchValues<T>) |
Pesquisa no intervalo especificado qualquer valor que não seja o especificado |
| ContainsAnyExcept<T>(Span<T>, T, T, T) |
Procura qualquer valor que não |
| ContainsAnyExcept<T>(Span<T>, T, T) |
Pesquisa no intervalo especificado qualquer valor que não |
| ContainsAnyExcept<T>(Span<T>, T) |
Pesquisa no intervalo especificado qualquer valor que não seja o especificado |
| ContainsAnyExceptInRange<T>(Span<T>, T, T) |
Procura qualquer valor fora do intervalo entre |
| ContainsAnyInRange<T>(Span<T>, T, T) |
Procura qualquer valor no intervalo entre |
| Count<T>(Span<T>, ReadOnlySpan<T>) |
Conta o número de vezes que o especificado |
| Count<T>(Span<T>, T) |
Conta o número de vezes que o especificado |
| EndsWith<T>(Span<T>, ReadOnlySpan<T>) |
Determina se a sequência especificada aparece no final de um vão. |
| IndexOf<T>(Span<T>, ReadOnlySpan<T>) |
Procura a sequência especificada e devolve o índice da sua primeira ocorrência. |
| IndexOf<T>(Span<T>, T) |
Procura o valor especificado e devolve o índice da sua primeira ocorrência. |
| IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Procura o primeiro índice de qualquer um dos valores especificados. |
| IndexOfAny<T>(Span<T>, SearchValues<T>) |
Procura o primeiro índice de qualquer um dos valores especificados. |
| IndexOfAny<T>(Span<T>, T, T, T) |
Procura o primeiro índice de qualquer um dos valores especificados. |
| IndexOfAny<T>(Span<T>, T, T) |
Procura o primeiro índice de qualquer um dos valores especificados. |
| IndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Procura o primeiro índice de qualquer valor diferente do especificado |
| IndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Procura o primeiro índice de qualquer valor diferente do especificado |
| IndexOfAnyExcept<T>(Span<T>, T, T, T) |
Procura o primeiro índice de qualquer valor que não |
| IndexOfAnyExcept<T>(Span<T>, T, T) |
Procura o primeiro índice de qualquer valor diferente dos dois valores especificados. |
| IndexOfAnyExcept<T>(Span<T>, T) |
Procura o primeiro índice de qualquer valor diferente do especificado |
| IndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Pesquisas pelo primeiro índice de qualquer valor fora do intervalo entre |
| IndexOfAnyInRange<T>(Span<T>, T, T) |
Procura o primeiro índice de qualquer valor no intervalo entre |
| LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) |
Procura a sequência especificada e devolve o índice da sua última ocorrência. |
| LastIndexOf<T>(Span<T>, T) |
Procura o valor especificado e devolve o índice da sua última ocorrência. |
| LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Procura o último índice de qualquer um dos valores especificados. |
| LastIndexOfAny<T>(Span<T>, SearchValues<T>) |
Procura o último índice de qualquer um dos valores especificados. |
| LastIndexOfAny<T>(Span<T>, T, T, T) |
Procura o último índice de qualquer um dos valores especificados. |
| LastIndexOfAny<T>(Span<T>, T, T) |
Procura o último índice de qualquer um dos valores especificados. |
| LastIndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Procura o último índice de qualquer valor diferente do especificado |
| LastIndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Procura o último índice de qualquer valor diferente do especificado |
| LastIndexOfAnyExcept<T>(Span<T>, T, T, T) |
Procura o último índice de qualquer valor diferente do especificado |
| LastIndexOfAnyExcept<T>(Span<T>, T, T) |
Procura o último índice de qualquer valor que não seja especificado |
| LastIndexOfAnyExcept<T>(Span<T>, T) |
Procura o último índice de qualquer valor diferente do especificado |
| LastIndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Pesquisa pelo último índice de qualquer valor fora do intervalo entre |
| LastIndexOfAnyInRange<T>(Span<T>, T, T) |
Procura o último índice de qualquer valor no intervalo entre |
| Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) |
Determina se um span e um span só de leitura se sobrepõem na memória e gera o deslocamento do elemento. |
| Overlaps<T>(Span<T>, ReadOnlySpan<T>) |
Determina se um span e um span só de leitura se sobrepõem na memória. |
| Replace<T>(Span<T>, T, T, IEqualityComparer<T>) |
Substitui todas as ocorrências de |
| Replace<T>(Span<T>, T, T) |
Substitui todas as ocorrências de |
| ReplaceAny<T>(Span<T>, SearchValues<T>, T) |
Substitui em |
| ReplaceAnyExcept<T>(Span<T>, SearchValues<T>, T) |
Substitui em |
| Reverse<T>(Span<T>) |
Inverte a sequência dos elementos em todo o intervalo. |
| SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>) |
Determina a ordem relativa de um intervalo e de um intervalo de apenas leitura comparando os elementos usando IComparable{T}. CompareTo(T). |
| SequenceEqual<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
Determina se duas sequências são iguais comparando os elementos usando um IEqualityComparer<T>. |
| SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) |
Determina se um span e um span só de leitura são iguais comparando os elementos usando IEquatable{T}. É igual a T. |
| Sort<T,TComparer>(Span<T>, TComparer) |
Ordena os elementos no todo Span<T> usando o |
| Sort<T>(Span<T>, Comparison<T>) |
Ordena os elementos no todo Span<T> usando o especificado Comparison<T>. |
| Sort<T>(Span<T>) |
Ordena os elementos do todo Span<T> usando a IComparable<T> implementação de cada elemento do Span<T>. |
| Sort<TKey,TValue,TComparer>(Span<TKey>, Span<TValue>, TComparer) |
Ordena um par de intervalos (um contendo as chaves e o outro com os itens correspondentes) com base nas chaves do primeiro Span<T> usando o comparador especificado. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>, Comparison<TKey>) |
Ordena um par de intervalos (um contendo as chaves e o outro contendo os itens correspondentes) com base nas chaves do primeiro Span<T> usando a comparação especificada. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>) |
Ordena um par de esferas (uma contendo as chaves e a outra contendo os itens correspondentes) com base nas chaves da primeira Span<T> usando a IComparable<T> implementação de cada chave. |
| StartsWith<T>(Span<T>, ReadOnlySpan<T>) |
Determina se uma sequência especificada aparece no início de um intervalo. |
| ToImmutableArray<T>(Span<T>) |
Converte o vão numa matriz imutável. |
| Trim<T>(Span<T>, ReadOnlySpan<T>) |
Remove todas as ocorrências iniciais e finais de um conjunto de elementos especificados num intervalo somente de leitura a partir de um intervalo. |
| Trim<T>(Span<T>, T) |
Remove todas as ocorrências dianteiras e posteriores de um elemento especificado de um vão. |
| TrimEnd<T>(Span<T>, ReadOnlySpan<T>) |
Remove todas as ocorrências finais de um conjunto de elementos especificados num intervalo apenas de leitura a partir de um intervalo. |
| TrimEnd<T>(Span<T>, T) |
Remove todas as ocorrências finais de um elemento especificado de um vão. |
| TrimStart<T>(Span<T>, ReadOnlySpan<T>) |
Remove todas as ocorrências iniciais de um conjunto de elementos especificados num intervalo de apenas leitura do espaço. |
| TrimStart<T>(Span<T>, T) |
Remove todas as ocorrências principais de um elemento especificado do espaço. |