Span<T> Struktur

Definition

Stellt eine typsichere und speichersichere Darstellung eines zusammenhängenden Speicherbereichs bereit.

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

Typparameter

T

Der Typ der Elemente im Span<T>.

Vererbung
Span<T>

Hinweise

Span<T> ist eine Ref-Struktur , die auf dem Stapel zugewiesen wird, anstatt auf dem verwalteten Heap. Ref-Strukturtypen verfügen über eine Reihe von Einschränkungen, um sicherzustellen, dass sie nicht auf den verwalteten Heap höher gestellt werden können, einschließlich, dass sie nicht boxen können, sie können nicht Variablen des Typs Objectdynamic oder einem beliebigen Schnittstellentyp zugewiesen werden, sie können keine Felder in einem Referenztyp sein, und sie können nicht über await yield alle Grenzen hinweg und grenzenübergreifend verwendet werden. Darüber hinaus rufen Sie zwei Methoden auf, Equals(Object) und GetHashCodegeben Sie eine NotSupportedException.

Wichtig

Da es sich um einen stapelgeschützten Typ handelt, Span<T> ist es nicht geeignet für viele Szenarien, die das Speichern von Verweisen auf Puffer auf dem Heap erfordern. Dies gilt beispielsweise für Routinen, die asynchrone Methodenaufrufe vornehmen. Für solche Szenarien können Sie die ergänzenden System.Memory<T> und System.ReadOnlyMemory<T> typen verwenden.

Verwenden Sie System.ReadOnlySpan<T>für Spannen, die unveränderliche oder schreibgeschützte Strukturen darstellen.

Bereich<T> und Arbeitsspeicher

A Span<T> stellt einen zusammenhängenden Bereich des beliebigen Speichers dar. Eine Span<T> Instanz wird häufig verwendet, um die Elemente eines Arrays oder eines Teils eines Arrays zu halten. Im Gegensatz zu einem Array kann eine Span<T> Instanz jedoch auf verwalteten Speicher, nativen Arbeitsspeicher oder auf dem Stapel verwalteten Speicher verweisen. Im folgenden Beispiel wird ein Span<Byte> Array erstellt:

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

Im folgenden Beispiel wird ein Span<Byte> von 100 Bytes systemeigener Arbeitsspeicher erstellt:

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

Im folgenden Beispiel wird das C# stackalloc-Schlüsselwort verwendet, um 100 Bytes Arbeitsspeicher im Stapel zuzuweisen:

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

Da Span<T> es sich um eine Abstraktion über einen beliebigen Speicherblock handelt, funktionieren Methoden des Typs und der Span<T> Methoden mit Parametern unabhängig Span<T> von der Art des Speichers, den Span<T> sie kapselt. So können beispielsweise alle separaten Codeabschnitte, die den Bereich initialisieren und die Summe seiner Elemente in einzelne Initialisierungs- und Berechnungsmethoden ändern, wie das folgende Beispiel veranschaulicht:

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

Bereich<T> und Arrays

Wenn es ein Array umschließt, Span<T> kann ein gesamtes Array umbrechen, wie es in den Beispielen im Abschnitt "Span<T> " und "Speicher " ausgeführt wurde. Da es die Slicing unterstützt, Span<T> kann auch auf einen zusammenhängenden Bereich innerhalb des Arrays verweisen.

Im folgenden Beispiel wird ein Datenschnitt der mittleren fünf Elemente eines ganzzahligen Arrays von 10 Elementen erstellt. Beachten Sie, dass der Code die Werte jeder ganze Zahl im Datenschnitt doppelt. Wie die Ausgabe zeigt, werden die von der Spanne vorgenommenen Änderungen in den Werten des Arrays angezeigt.

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

Spannen<T> und Datenschnitte

Span<T> enthält zwei Überladungen der Slice Methode, die einen Datenschnitt aus dem aktuellen Bereich bilden, der bei einem angegebenen Index beginnt. Dies ermöglicht es, die Daten in einem Span<T> Satz logischer Blöcke zu behandeln, die nach Bedarf durch Teile einer Datenverarbeitungspipeline mit minimalem Leistungseffekt verarbeitet werden können. Da beispielsweise moderne Serverprotokolle häufig textbasiert sind, ist die Manipulation von Zeichenfolgen und Unterzeichenfolgen besonders wichtig. In der String Klasse ist Substringdie Hauptmethode zum Extrahieren von Teilzeichenfolgen . Für Datenpipelinen, die sich auf umfangreiche Zeichenfolgenbearbeitung verlassen, bietet seine Verwendung einige Leistungsstrafen, da sie:

  1. Erstellt eine neue Zeichenfolge, um die Unterzeichenfolge zu halten.

  2. Kopiert eine Teilmenge der Zeichen aus der ursprünglichen Zeichenfolge in die neue Zeichenfolge.

Dieser Zuordnungs- und Kopiervorgang kann mithilfe von entweder Span<T> oder ReadOnlySpan<T>, wie das folgende Beispiel zeigt, entfernt werden:

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

Konstruktoren

Span<T>(T[])

Erstellt ein neues Span<T>-Objekt über das gesamte angegebene Array.

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

Erstellt ein neues Span<T>-Objekt, das eine angegebene Anzahl von Elementen aus einem Array enthält. Dabei wird an einem angegebenen Index begonnen.

Span<T>(Void*, Int32)

Erstellt ein neues Span<T>-Objekt aus einer angegebenen Anzahl von T-Elementen. Dabei wird an der angegebenen Speicheradresse begonnen.

Eigenschaften

Empty

Gibt ein leeres Span<T>-Objekt zurück.

IsEmpty

Gibt einen Wert zurück, der angibt, ob das aktuelle Span<T>-Element leer ist.

Item[Int32]

Ruft das Element am angegebenen nullbasierten Index ab.

Length

Gibt die Länge des aktuellen Span-Elements fest.

Methoden

Clear()

Löscht den Inhalt dieses Span<T>-Objekts.

CopyTo(Span<T>)

Kopiert die Inhalte dieses Span<T>-Elements in ein Span<T>-Zielelement.

Equals(Object)
Veraltet.
Veraltet.

Das Aufrufen dieser Methode wird nicht unterstützt.

Fill(T)

Füllt die Elemente dieses Span-Elements mit einem angegebenen Wert auf.

GetEnumerator()

Gibt einen Enumerator für dieses Span<T>-Element zurück.

GetHashCode()
Veraltet.

Löst eine NotSupportedException aus.

GetPinnableReference()

Gibt einen Verweis auf ein Objekt vom Typ T zurück, das zum Anheften verwendet werden kann.

Diese Methode soll .NET-Compiler unterstützen und nicht vom Benutzercode aufgerufen werden.

Slice(Int32)

Bildet einen Slice aus dem aktuellen Span-Element, das an einem angegebenen Index beginnt.

Slice(Int32, Int32)

Bildet einen Slice aus dem aktuellen Span-Element. Dabei wird an einem angegebenen Index für eine angegebene Länge begonnen.

ToArray()

Kopiert die Inhalte dieses Span-Elements in ein neues Array.

ToString()

Gibt die Zeichenfolgendarstellung dieses Span<T>-Objekts zurück.

TryCopyTo(Span<T>)

Versucht, das aktuelle Span<T>-Element in ein Span<T>-Zielelement zu kopieren und gibt einen Wert zurück, der angibt, ob der Kopiervorgang erfolgreich war.

Operatoren

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

Gibt einen Wert zurück, der angibt, ob zwei Span<T>-Objekte gleich sind.

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

Definiert eine implizite Konvertierung von ArraySegment<T> in Span<T>.

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

Definiert eine implizite Konvertierung von Span<T> in ReadOnlySpan<T>.

Implicit(T[] to Span<T>)

Definiert eine implizite Konvertierung eines Arrays in Span<T>.

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

Gibt einen Wert zurück, der angibt, ob zwei Span<T>-Objekte ungleich sind.

Erweiterungsmethoden

ToImmutableArray<T>(Span<T>)

Wandelt den Bereich in ein unveränderliches Array um.

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

Durchsucht ein ganzes sortiertes Span<T> mithilfe der angegebenen generischen IComparable<T>-Schnittstelle nach einem Wert.

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

Durchsucht ein ganzes sortiertes Span<T> mithilfe des angegebenen generischen TComparer-Typs nach einem angegebenen Wert.

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

Durchsucht ein ganzes sortiertes Span<T> mithilfe des angegebenen generischen TComparable-Typs nach einem Wert.

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

Sucht die Länge eines gemeinsamen Präfixes, das zwischen span und other.

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

Sucht die Länge eines gemeinsamen Präfixes, das zwischen span und other.

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

Gibt an, ob ein angegebener Wert in einer Spanne gefunden wird. Werte werden mit „IEquatable{T}.Equals(T)“ verglichen.

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

Bestimmt, ob die angegebene Sequenz am Ende einer Spanne angezeigt wird.

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

Sucht nach dem angegebenen Wert und gibt den Index des ersten Vorkommens zurück. Werte werden mit „IEquatable{T}.Equals(T)“ verglichen.

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

Sucht nach der angegebenen Sequenz und gibt den Index des ersten Vorkommens zurück. Werte werden mit „IEquatable{T}.Equals(T)“ verglichen.

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

Sucht nach dem ersten Index eines der angegebenen Werte, ähnlich dem mehrmaligen Aufruf von IndexOf mit dem logischen OR-Operator (ODER).

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

Sucht nach dem ersten Index eines der angegebenen Werte, ähnlich dem mehrmaligen Aufruf von IndexOf mit dem logischen OR-Operator (ODER).

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

Sucht nach dem ersten Index eines der angegebenen Werte, ähnlich dem mehrmaligen Aufruf von IndexOf mit dem logischen OR-Operator (ODER).

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

Sucht nach dem ersten Index eines anderen Werts als dem angegebenen value.

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

Sucht nach dem ersten Index eines anderen Werts als der angegebenen value0 oder value1.

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

Sucht nach dem ersten Index eines anderen Werts als dem angegebenen value0, value1oder value2.

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

Sucht nach dem ersten Index eines anderen Werts als dem angegebenen values.

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

Sucht nach dem angegebenen Wert und gibt den Index des letzten Vorkommens zurück. Werte werden mit „IEquatable{T}.Equals(T)“ verglichen.

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

Sucht nach der angegebenen Sequenz und gibt den Index des letzten Vorkommens zurück. Werte werden mit „IEquatable{T}.Equals(T)“ verglichen.

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

Sucht nach dem letzten Index eines der angegebenen Werte, ähnlich dem mehrmaligen Aufruf von LastIndexOf mit dem logischen OR-Operator (ODER).

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

Sucht nach dem letzten Index eines der angegebenen Werte, ähnlich dem mehrmaligen Aufruf von LastIndexOf mit dem logischen OR-Operator (ODER).

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

Sucht nach dem letzten Index eines der angegebenen Werte, ähnlich dem mehrmaligen Aufruf von LastIndexOf mit dem logischen OR-Operator (ODER).

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

Sucht nach dem letzten Index eines anderen Werts als dem angegebenen value.

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

Sucht nach dem letzten Index eines anderen Werts als dem angegebenen value0 oder value1.

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

Sucht nach dem letzten Index eines anderen Werts als dem angegebenen value0, value1oder value2.

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

Sucht nach dem letzten Index eines anderen Werts als dem angegebenen values.

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

Bestimmt, ob sich eine Spanne und eine schreibgeschützte Spanne im Speicher überlappen.

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

Bestimmt, ob sich eine Spanne und eine schreibgeschützte Spanne im Speicher überlappen, und gibt den Elementoffset aus.

Reverse<T>(Span<T>)

Kehrt die Reihenfolge der Elemente in der gesamten Spanne um.

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

Bestimmt die relative Reihenfolge von einer Spanne und einer schreibgeschützten Spanne durch Vergleichen der Elemente mit „IComparable{T}.CompareTo(T)“.

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

Bestimmt, ob eine Spanne und eine schreibgeschützte Spanne identisch sind, indem die Elemente mit „IEquatable{T}.Equals(T)“ verglichen werden.

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

Bestimmt, ob zwei Sequenzen gleich sind, indem sie die Elemente mithilfe einer IEqualityComparer<T>.

Sort<T>(Span<T>)

Sortiert die Elemente in der Gesamten Span<T> mithilfe der IComparable<T> Implementierung jedes Elements des Span<T>.

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

Sortiert die Elemente in der gesamten Span<T> mithilfe des angegebenen Comparison<T>.

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

Sortiert die Elemente innerhalb von Span<T> mithilfe von TComparer.

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

Sortiert ein Paar von Spannen (eine enthält die Schlüssel und die andere die entsprechenden Elemente) auf Basis der Schlüssel in der ersten Schnittstelle Span<T> und mithilfe der IComparable<T>-Implementierung der einzelnen Schlüssel.

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

Sortiert ein Paar von Spannen (eine enthält die Schlüssel und die andere die entsprechenden Elemente) auf Basis der Schlüssel in der ersten Schnittstelle Span<T> und mithilfe des angegebenen Vergleichs.

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

Sortiert ein Paar von Spannen (eine enthält die Schlüssel und die andere die entsprechenden Elemente) auf Basis der Schlüssel in der ersten Schnittstelle Span<T> und mithilfe der angegebenen Vergleichsfunktion.

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

Bestimmt, ob eine angegebene Sequenz am Anfang einer Spanne angezeigt wird.

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

Entfernt alle führenden und nachfolgenden Vorkommen eines angegebenen Elements aus einer Spanne.

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

Entfernt alle führenden und nachfolgenden Vorkommen einer Reihe von Elementen, die in einer schreibgeschützten Spanne angegeben sind, aus einer Spanne.

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

Entfernt alle nachfolgenden Vorkommen eines angegebenen Elements aus einer Spanne.

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

Entfernt alle nachfolgenden Vorkommen einer Reihe von Elementen, die in einer schreibgeschützten Spanne angegeben sind, aus einer Spanne.

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

Entfernt alle führenden Vorkommen eines bestimmten Elements aus der Spanne.

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

Entfernt alle führenden Vorkommen einer Reihe von Elementen, die in einer schreibgeschützten Spanne angegeben sind, aus der Spanne.

Gilt für:

Siehe auch