Span<T> Struktura

Definice

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

generic <typename T>
public value class Span
public readonly ref struct Span<T>
[System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))]
public readonly ref struct Span<T>
type Span<'T> = struct
[<System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))>]
type Span<'T> = struct
Public Structure Span(Of T)

Parametry typu

T

Typ položek v souboru Span<T>.

Dědičnost
Span<T>
Atributy

Poznámky

Span<T> je ref struktura , která je přidělena v zásobníku, nikoli ve spravované haldě. Typy struktury ref mají řadu omezení, která zajišťují, že je nelze povýšit na spravovanou haldu, včetně toho, že je nelze zařazovat do rámečku, nelze je přiřadit k proměnným typu Objectdynamic nebo k žádnému typu rozhraní, nemohou být poli v referenčním typu a nelze je použít napříč await hranicemiyield. Kromě toho volání dvou metod, Equals(Object) a GetHashCode, vyvolá .NotSupportedException

Důležité

Vzhledem k tomu, že se jedná o pouze zásobníkový typ, Span<T> není vhodný pro mnoho scénářů, které vyžadují ukládání odkazů na vyrovnávací paměti na haldě. To platí například pro rutiny, které provádí asynchronní volání metod. Pro takové scénáře můžete použít doplňky System.Memory<T> a System.ReadOnlyMemory<T> typy.

Pro rozsahy, které představují neměnné struktury nebo struktury jen pro čtení, použijte System.ReadOnlySpan<T>.

Span<T> a paměť

Objekt Span<T> představuje souvislou oblast libovolné paměti. Instance Span<T> se často používá k uložení prvků pole nebo části pole. Na rozdíl od pole však instance může odkazovat na spravovanou Span<T> paměť, nativní paměť nebo paměť spravovanou v zásobníku. Následující příklad vytvoří Span<Byte> z pole :

// 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

Následující příklad vytvoří Span<Byte> ze 100 bajtů nativní paměti:

// 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

Následující příklad používá klíčové slovo stackalloc jazyka C# k přidělení 100 bajtů paměti v zásobníku:

// 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

Vzhledem k tomu Span<T> , že je abstrakce nad libovolným blokem paměti, metody Span<T> typu a metody s Span<T> parametry pracují s libovolným Span<T> objektem bez ohledu na druh paměti, který zapouzdřuje. Například každou ze samostatných částí kódu, které inicializují rozsah a vypočítají součet jeho prvků, lze změnit na jednu inicializační a výpočetní metodu, jak ukazuje následující příklad:

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

Rozsah<T> a pole

Když zabalí pole, Span<T> může zabalit celé pole, jako to udělal v příkladech v části Span<T> a paměť . Protože podporuje vytváření řezů, Span<T> může také odkazovat na libovolnou souvislou oblast v rámci pole.

Následující příklad vytvoří řez prostředních pěti prvků celočíselného pole 10 prvků. Všimněte si, že kód zdvojnásobuje hodnoty každého celého čísla v řezu. Jak ukazuje výstup, změny provedené rozsahem se projeví v hodnotách pole.

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

Rozprostřit<T> a řezy

Span<T> zahrnuje dvě přetížení Slice metody, která tvoří řez z aktuálního rozsahu, který začíná na zadaném indexu. To umožňuje zacházet s daty v Span<T> souboru jako se sadou logických bloků dat, které lze podle potřeby zpracovat částmi kanálu zpracování dat s minimálním dopadem na výkon. Vzhledem k tomu, že moderní serverové protokoly jsou často založené na textu, je obzvláště důležitá manipulace s řetězci a podřetězci. String Ve třídě je Substringhlavní metodou extrakce podřetěžků . U datových kanálů, které se spoléhají na rozsáhlou manipulaci s řetězci, nabízí jeho použití určité sankce za výkon, protože:

  1. Vytvoří nový řetězec pro uložení podřetězce.

  2. Zkopíruje podmnožinu znaků z původního řetězce do nového řetězce.

Tuto operaci přidělení a kopírování lze eliminovat pomocí nebo Span<T>ReadOnlySpan<T>, jak ukazuje následující příklad:

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

Konstruktory

Span<T>(T)

Vytvoří nový Span<T> o délce 1 kolem zadaného odkazu.

Span<T>(T[])

Vytvoří nový Span<T> objekt v celém zadaném poli.

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

Vytvoří nový Span<T> objekt, který obsahuje zadaný počet prvků pole počínaje zadaným indexem.

Span<T>(Void*, Int32)

Vytvoří nový Span<T> objekt ze zadaného T počtu prvků počínaje zadanou adresou paměti.

Vlastnosti

Empty

Vrátí prázdný Span<T> objekt.

IsEmpty

Vrátí hodnotu, která označuje, jestli je aktuální Span<T> hodnota prázdná.

Item[Int32]

Získá prvek na zadaném indexu založeném na nule.

Length

Vrátí délku aktuálního rozsahu.

Metody

Clear()

Vymaže obsah tohoto Span<T> objektu.

CopyTo(Span<T>)

Zkopíruje obsah do Span<T> cílového objektu Span<T>.

Equals(Object)
Zastaralé.
Zastaralé.

Volání této metody nejsou podporována.

Fill(T)

Vyplní prvky tohoto rozsahu zadanou hodnotou.

GetEnumerator()

Vrátí enumerátor pro tento Span<T>objekt .

GetHashCode()
Zastaralé.

Vyvolá .NotSupportedException

GetPinnableReference()

Vrátí odkaz na objekt typu T, který lze použít pro připnutí.

Tato metoda je určena pro podporu kompilátorů .NET a není určena k zavolání uživatelským kódem.

Slice(Int32)

Vytvoří řez z aktuálního rozsahu, který začíná v zadaném indexu.

Slice(Int32, Int32)

Vytvoří řez z aktuálního rozsahu začínající na zadaném indexu pro zadanou délku.

ToArray()

Zkopíruje obsah tohoto rozsahu do nového pole.

ToString()

Vrátí řetězcovou reprezentaci tohoto Span<T> objektu.

TryCopyTo(Span<T>)

Pokusí se zkopírovat aktuální Span<T> do cíle Span<T> a vrátí hodnotu, která označuje, jestli operace kopírování proběhla úspěšně.

Operátory

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

Vrátí hodnotu, která označuje, zda jsou dva Span<T> objekty rovny.

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

Definuje implicitní převod objektu ArraySegment<T> na Span<T>.

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

Definuje implicitní převod objektu Span<T> na ReadOnlySpan<T>.

Implicit(T[] to Span<T>)

Definuje implicitní převod pole na Span<T>.

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

Vrátí hodnotu, která označuje, zda si dva Span<T> objekty nejsou rovny.

Metody rozšíření

ToImmutableArray<T>(Span<T>)

Převede rozsah na neměnné pole.

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

Prohledá celé seřazené Span<T> hodnoty pomocí zadaného IComparable<T> obecného rozhraní.

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

Vyhledá v celém seřazeném Span<T> souboru zadanou hodnotu pomocí zadaného TComparer obecného typu.

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

Vyhledá hodnotu se zadaným TComparable obecným typem v celém seřazeném Span<T> souboru.

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

Najde délku jakékoli společné předpony sdílené mezi span a other.

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

Najde délku jakékoli společné předpony sdílené mezi span a other.

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

Určuje, zda je zadaná hodnota nalezena v rozsahu. Hodnoty se porovnávají pomocí IEquatable{T}. Rovná se(T).

Count<T>(Span<T>, T)

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Určuje, zda se zadaná sekvence zobrazí na konci rozsahu.

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

Vyhledá zadanou hodnotu a vrátí index jejího prvního výskytu. Hodnoty se porovnávají pomocí IEquatable{T}. Rovná se(T).

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

Vyhledá zadanou sekvenci a vrátí index jejího prvního výskytu. Hodnoty se porovnávají pomocí IEquatable{T}. Rovná se(T).

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

Vyhledá první index libovolné ze zadaných hodnot, podobně jako volání IndexOf několikrát pomocí logického operátoru OR.

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

Vyhledá první index libovolné ze zadaných hodnot, podobně jako volání IndexOf několikrát pomocí logického operátoru OR.

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

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Vyhledá první index libovolné ze zadaných hodnot, podobně jako volání IndexOf několikrát pomocí logického operátoru OR.

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

Vyhledá první index jakékoli hodnoty kromě zadané valuehodnoty .

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

Vyhledá první index libovolné hodnoty kromě zadané value0 hodnoty nebo value1.

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

Vyhledá první index libovolné hodnoty kromě zadané value0hodnoty , value1nebo value2.

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

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Vyhledá první index jakékoli hodnoty kromě zadané valueshodnoty .

IndexOfAnyExceptInRange<T>(Span<T>, T, T)

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

IndexOfAnyInRange<T>(Span<T>, T, T)

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Vyhledá zadanou hodnotu a vrátí index jejího posledního výskytu. Hodnoty se porovnávají pomocí IEquatable{T}. Rovná se(T).

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

Vyhledá zadanou sekvenci a vrátí index jejího posledního výskytu. Hodnoty se porovnávají pomocí IEquatable{T}. Rovná se(T).

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

Vyhledá poslední index libovolné ze zadaných hodnot podobně jako volání LastIndexOf několikrát pomocí logického operátoru OR.

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

Vyhledá poslední index libovolné ze zadaných hodnot podobně jako volání LastIndexOf několikrát pomocí logického operátoru OR.

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

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Vyhledá poslední index libovolné ze zadaných hodnot podobně jako volání LastIndexOf několikrát pomocí logického operátoru OR.

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

Vyhledá poslední index libovolné hodnoty kromě zadané valuehodnoty .

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

Vyhledá poslední index libovolné hodnoty kromě zadané value0 hodnoty nebo value1.

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

Vyhledá poslední index libovolné hodnoty kromě zadané value0hodnoty , value1nebo value2.

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

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Vyhledá poslední index libovolné hodnoty kromě zadané valueshodnoty .

LastIndexOfAnyExceptInRange<T>(Span<T>, T, T)

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

LastIndexOfAnyInRange<T>(Span<T>, T, T)

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

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

Určuje, zda se rozsah a rozsah jen pro čtení překrývají v paměti.

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

Určuje, zda se rozsah a rozsah jen pro čtení překrývají v paměti, a výstupem posun prvku.

Replace<T>(Span<T>, T, T)

Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.

Reverse<T>(Span<T>)

Obrátí sekvenci prvků v celém rozsahu.

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

Určuje relativní pořadí rozsahu a rozsahu jen pro čtení porovnáním prvků pomocí funkce IComparable{T}. CompareTo(T).

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

Určuje, zda je rozsah a rozsah jen pro čtení shodný, porovnáním prvků pomocí funkce IEquatable{T}. Rovná se(T).

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

Určuje, zda jsou dvě sekvence rovny porovnáním prvků pomocí .IEqualityComparer<T>

Sort<T>(Span<T>)

Seřadí prvky v celém Span<T> objektu IComparable<T> pomocí implementace každého prvku Span<T>.

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

Seřadí prvky v celém Span<T> objektu pomocí zadaného Comparison<T>objektu .

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

Seřadí prvky v celém Span<T> objektu TComparerpomocí .

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

Seřadí dvojici rozsahů (jedno obsahuje klíče a druhé odpovídající položky) na základě klíčů v prvním Span<T> s použitím IComparable<T> implementace každého klíče.

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

Seřadí dvojici rozsahů (jedno obsahuje klíče a druhé odpovídající položky) na základě klíčů v prvním Span<T> z nich pomocí zadaného porovnání.

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

Seřadí dvojici rozsahů (jedno obsahuje klíče a druhé odpovídající položky) na základě klíčů v prvním Span<T> z nich pomocí zadaného porovnávače.

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

Určuje, zda se zadaná sekvence zobrazí na začátku rozsahu.

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

Odebere všechny počáteční a koncové výskyty zadaného prvku z rozsahu.

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

Odebere všechny počáteční a koncové výskyty sady prvků zadané v rozsahu jen pro čtení z rozsahu.

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

Odebere všechny koncové výskyty zadaného prvku z rozsahu.

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

Odebere všechny koncové výskyty sady prvků zadané v rozsahu jen pro čtení z rozsahu.

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

Odebere všechny počáteční výskyty zadaného prvku z rozsahu.

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

Odebere všechny počáteční výskyty sady prvků zadané v rozsahu jen pro čtení z rozsahu.

Platí pro

Viz také