Span<T> Estrutura

Definição

Fornece uma representação segura de memória e de tipo de uma região contígua de memória arbitrária.

generic <typename T>
public value class Span
public readonly ref struct Span<T>
type Span<'T> = struct
Public Structure Span(Of T)

Parâmetros de tipo

T

O tipo de itens no Span<T>.

Herança
Span<T>

Comentários

Span<T> é um struct ref alocado na pilha em vez de no heap gerenciado. Os tipos de struct ref têm várias restrições para garantir que não possam ser promovidos ao heap gerenciado, incluindo que não podem ser em caixa, não podem ser atribuídos a variáveis de tipo Objectdynamic ou a qualquer tipo de interface, não podem ser campos em um tipo de referência e não podem ser usados entre await limites.yield Além disso, chamadas para dois métodos Equals(Object) e GetHashCode, gerar um NotSupportedException.

Importante

Como ele é um tipo somente pilha, Span<T> é inadequado para muitos cenários que exigem o armazenamento de referências para buffers no heap. Isso é verdadeiro, por exemplo, de rotinas que fazem chamadas de método assíncronas. Para esses cenários, você pode usar os tipos e System.ReadOnlyMemory<T> complementaresSystem.Memory<T>.

Para intervalos que representam estruturas imutáveis ou somente leitura, use System.ReadOnlySpan<T>.

Extensão<T> e memória

Um Span<T> representa uma região contígua de memória arbitrária. Uma Span<T> instância geralmente é usada para conter os elementos de uma matriz ou uma parte de uma matriz. Ao contrário de uma matriz, no entanto, uma Span<T> instância pode apontar para memória gerenciada, memória nativa ou memória gerenciada na pilha. O exemplo a seguir cria uma Span<Byte> 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> 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 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 do Span<T> tipo e métodos com Span<T> parâmetros operam em qualquer Span<T> objeto, independentemente do tipo de memória que encapsula. Por exemplo, cada uma das seções separadas de código que inicializam o intervalo e calculam a soma de seus elementos pode ser alterada em métodos de inicialização e cálculo únicos, 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

Intervalo<T> e matrizes

Quando ele encapsula uma matriz, Span<T> pode encapsular uma matriz inteira, como fez nos exemplos na seção Intervalo<T> e memória . Como ele dá suporte ao 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 intermediários de uma matriz de inteiro 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 intervalo 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

Intervalo<T> e fatias

Span<T> inclui duas sobrecargas do Slice método que formam uma fatia do intervalo atual que começa em um índice especificado. Isso possibilita tratar os dados em um Span<T> conjunto de partes lógicas que podem ser processadas 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 cadeias de caracteres e subcadeias de caracteres é particularmente importante. String Na classe, o método principal para extrair subcadeias de caracteres é Substring. Para pipelines de dados que dependem de manipulação abrangente de cadeia de caracteres, seu uso oferece algumas penalidades de desempenho, já que:

  1. Cria uma nova cadeia de caracteres para manter a subcadeia de caracteres.

  2. 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 ou Span<T> ReadOnlySpan<T>, como mostra o exemplo a seguir:

using System;

class Program2
{
    static void Main()
    {
        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

Span<T>(T[])

Cria um novo objeto Span<T> sobre a totalidade de uma matriz especificada.

Span<T>(T[], Int32, Int32)

Cria um novo objeto Span<T> que inclui um número especificado de elementos de uma matriz, começando em um índice especificado.

Span<T>(Void*, Int32)

Cria um objeto Span<T> com base em um número especificado de elementos T, começando em um endereço de memória especificado.

Propriedades

Empty

Retorna um objeto Span<T> vazio.

IsEmpty

Retorna um valor que indica se o Span<T> atual está vazio.

Item[Int32]

Obtém o elemento no índice baseado em zero especificado.

Length

Retorna o tamanho do intervalo atual.

Métodos

Clear()

Limpa o conteúdo deste objeto Span<T>.

CopyTo(Span<T>)

Copia o conteúdo deste Span<T> para um Span<T> de destino.

Equals(Object)
Obsoleto.
Obsoleto.

Não há suporte para chamadas a esse método.

Fill(T)

Preenche os elementos desse intervalo com um valor especificado.

GetEnumerator()

Retorna um enumerador para este Span<T>.

GetHashCode()
Obsoleto.

Gera uma NotSupportedException.

GetPinnableReference()

Retorna uma referência a um objeto do tipo T que pode ser usado para fixação.

Esse método destina-se a dar suporte a compiladores .NET e não se destina a ser chamado pelo código do usuário.

Slice(Int32)

Forma uma fatia com base no intervalo atual que começa em um índice especificado.

Slice(Int32, Int32)

Forma uma fatia com base no intervalo atual que começa em um índice especificado para um tamanho especificado.

ToArray()

Copia o conteúdo desse intervalo para uma nova matriz.

ToString()

Retorna a representação de cadeia de caracteres desse objeto Span<T>.

TryCopyTo(Span<T>)

Tenta copiar o Span<T> atual para um Span<T> de destino e retorna um valor que indica se a operação de cópia foi bem-sucedida.

Operadores

Equality(Span<T>, Span<T>)

Retorna um valor que indica se dois objetos Span<T> são iguais.

Implicit(ArraySegment<T> to Span<T>)

Define uma conversão implícita de um ArraySegment<T> em um Span<T>.

Implicit(Span<T> to ReadOnlySpan<T>)

Define uma conversão implícita de um Span<T> em um ReadOnlySpan<T>.

Implicit(T[] to Span<T>)

Define uma conversão implícita de uma matriz em um Span<T>.

Inequality(Span<T>, Span<T>)

Retorna um valor que indica se dois objetos Span<T> não são iguais.

Métodos de Extensão

ToImmutableArray<T>(Span<T>)

Converte o intervalo em uma matriz imutável.

BinarySearch<T>(Span<T>, IComparable<T>)

Pesquisa um Span<T> inteiro classificado por um valor usando a interface genérica IComparable<T> especificada.

BinarySearch<T,TComparer>(Span<T>, T, TComparer)

Pesquisa um Span<T> inteiro classificado por um valor especificado usando o tipo genérico TComparer especificado.

BinarySearch<T,TComparable>(Span<T>, TComparable)

Pesquisa um Span<T> inteiro classificado por um valor usando o tipo genérico TComparable especificado.

CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>)

Localiza o comprimento de qualquer prefixo comum compartilhado entre span e other.

CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>)

Localiza o comprimento de qualquer prefixo comum compartilhado entre span e other.

Contains<T>(Span<T>, T)

Indica se um valor especificado é encontrado em um intervalo. Os valores são comparados usando IEquatable{T}.Equals(T).

EndsWith<T>(Span<T>, ReadOnlySpan<T>)

Determina se a sequência especificada aparece no final de um intervalo.

IndexOf<T>(Span<T>, T)

Pesquisa o valor especificado e retorna o índice de sua primeira ocorrência. Os valores são comparados usando IEquatable{T}.Equals(T).

IndexOf<T>(Span<T>, ReadOnlySpan<T>)

Pesquisa a sequência especificada e retorna o índice de sua primeira ocorrência. Os valores são comparados usando IEquatable{T}.Equals(T).

IndexOfAny<T>(Span<T>, T, T)

Pesquisa o primeiro índice de qualquer um dos valores especificados, semelhante à chamada de IndexOf várias vezes com o operador OR lógico.

IndexOfAny<T>(Span<T>, T, T, T)

Pesquisa o primeiro índice de qualquer um dos valores especificados, semelhante à chamada de IndexOf várias vezes com o operador OR lógico.

IndexOfAny<T>(Span<T>, ReadOnlySpan<T>)

Pesquisa o primeiro índice de qualquer um dos valores especificados, semelhante à chamada de IndexOf várias vezes com o operador OR lógico.

IndexOfAnyExcept<T>(Span<T>, T)

Pesquisa o primeiro índice de qualquer valor diferente do especificado value.

IndexOfAnyExcept<T>(Span<T>, T, T)

Pesquisa o primeiro índice de qualquer valor diferente do especificado value0 ou value1.

IndexOfAnyExcept<T>(Span<T>, T, T, T)

Pesquisa o primeiro índice de qualquer valor diferente do especificado value0, value1ou value2.

IndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>)

Pesquisa o primeiro índice de qualquer valor diferente do especificado values.

LastIndexOf<T>(Span<T>, T)

Pesquisa o valor especificado e retorna o índice de sua última ocorrência. Os valores são comparados usando IEquatable{T}.Equals(T).

LastIndexOf<T>(Span<T>, ReadOnlySpan<T>)

Pesquisa a sequência especificada e retorna o índice de sua última ocorrência. Os valores são comparados usando IEquatable{T}.Equals(T).

LastIndexOfAny<T>(Span<T>, T, T)

Pesquisa o último índice de qualquer um dos valores especificados, semelhante à chamada de LastIndexOf várias vezes com o operador OR lógico.

LastIndexOfAny<T>(Span<T>, T, T, T)

Pesquisa o último índice de qualquer um dos valores especificados, semelhante à chamada de LastIndexOf várias vezes com o operador OR lógico.

LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>)

Pesquisa o último índice de qualquer um dos valores especificados, semelhante à chamada de LastIndexOf várias vezes com o operador OR lógico.

LastIndexOfAnyExcept<T>(Span<T>, T)

Pesquisa o último índice de qualquer valor diferente do especificado value.

LastIndexOfAnyExcept<T>(Span<T>, T, T)

Pesquisa o último índice de qualquer valor diferente do especificado value0 ou value1.

LastIndexOfAnyExcept<T>(Span<T>, T, T, T)

Pesquisa o último índice de qualquer valor diferente do especificado value0, value1ou value2.

LastIndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>)

Pesquisa o último índice de qualquer valor diferente do especificado values.

Overlaps<T>(Span<T>, ReadOnlySpan<T>)

Determina se um intervalo e um intervalo somente leitura se sobrepõem na memória.

Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32)

Determina se um intervalo e um intervalo somente leitura se sobrepõem na memória e gera o deslocamento do elemento.

Reverse<T>(Span<T>)

Reverte a sequência dos elementos em todo o intervalo.

SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>)

Determina a ordem relativa de um intervalo e um intervalo somente leitura comparando os elementos com o uso de IComparable{T}.CompareTo(T).

SequenceEqual<T>(Span<T>, ReadOnlySpan<T>)

Determina se um intervalo e um intervalo somente leitura são iguais comparando os elementos com o uso de IEquatable{T}.Equals(T).

SequenceEqual<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>)

Determina se duas sequências são iguais comparando os elementos usando um IEqualityComparer<T>.

Sort<T>(Span<T>)

Classifica os elementos no todo Span<T> usando a IComparable<T> implementação de cada elemento do Span<T>.

Sort<T>(Span<T>, Comparison<T>)

Classifica os elementos em todo o Span<T> usando o Comparison<T> especificado.

Sort<T,TComparer>(Span<T>, TComparer)

Classifica os elementos em todo o Span<T> usando o TComparer.

Sort<TKey,TValue>(Span<TKey>, Span<TValue>)

Classifica 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 implementação IComparable<T> de cada chave.

Sort<TKey,TValue>(Span<TKey>, Span<TValue>, Comparison<TKey>)

Classifica 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,TComparer>(Span<TKey>, Span<TValue>, TComparer)

Classifica um par de intervalos (um contendo as chaves e o outro contendo os itens correspondentes) com base nas chaves do primeiro Span<T> usando o comparador especificado.

StartsWith<T>(Span<T>, ReadOnlySpan<T>)

Determina se uma sequência especificada aparece no início de um intervalo.

Trim<T>(Span<T>, T)

Remove todas as ocorrências à esquerda e à direita de um elemento especificado de um intervalo.

Trim<T>(Span<T>, ReadOnlySpan<T>)

Remove todas as ocorrências à esquerda e à direita de um conjunto de elementos especificado em um intervalo somente leitura de um intervalo.

TrimEnd<T>(Span<T>, T)

Remove todas as ocorrências à direita de um elemento especificado de um intervalo.

TrimEnd<T>(Span<T>, ReadOnlySpan<T>)

Remove todas as ocorrências à direita de um conjunto de elementos especificado em um intervalo somente leitura de um intervalo.

TrimStart<T>(Span<T>, T)

Remove todas as ocorrências à esquerda de um elemento especificado do intervalo.

TrimStart<T>(Span<T>, ReadOnlySpan<T>)

Remove todas as ocorrências à esquerda de um conjunto de elementos especificado em um intervalo somente leitura do intervalo.

Aplica-se a

Confira também