Span<T> Struktura
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Poskytuje typově bezpečnou a paměťově bezpečnou reprezentaci souvislé oblasti libovolné paměti.
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)
Parametry typu
- T
Typ položek v sadě Span<T>.
- Dědičnost
- Atributy
Poznámky
Typ Span<T> je struktura odkazu , která je přidělena v zásobníku, nikoli ve spravované haldě. Typy ref struktur mají určitá omezení, aby se zajistilo, že je nelze zvýšit na spravovanou haldu, včetně toho, že nemohou být:
- Krabici.
- Přiřazeno proměnným typu Object nebo
dynamicnebo libovolnému typu rozhraní. - Pole v referenčním typu
- Používá se přes
awaithranice.yield
Kromě toho volání dvou metod Equals(Object) a GetHashCode vyvolávají NotSupportedException.
Important
Vzhledem k tomu, že se jedná o typ pouze zásobníku, Span<T> není vhodný pro mnoho scénářů, které vyžadují ukládání odkazů na vyrovnávací paměti v haldě. To platí například u rutin, které provádí asynchronní volání metod. V takových scénářích můžete použít doplňkové typy System.Memory<T> a System.ReadOnlyMemory<T>.
Pro rozsahy, které představují struktury, jež jsou neměnné nebo pouze pro čtení, použijte System.ReadOnlySpan<T>.
Memory
A 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 ale Span<T> instance může odkazovat na spravovanou 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> z 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
Protože Span<T> je abstrakce nad libovolným blokem paměti, metody typu Span<T> a metody s parametry Span<T> pracují na libovolném Span<T> objektu bez ohledu na druh paměti, který zapouzdř Například každý z samostatných částí kódu, které inicializují rozsah a vypočítají součet jeho prvků, lze refaktorovat do jedné inicializace a výpočetních metod, 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
Pole
Když obaluje pole, Span<T> může obalit celé pole, stejně jako tomu bylo v příkladech v části Paměť. Protože podporuje řezy, 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ásobí 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
Řezy
Span<T> obsahuje dvě přetížení Slice metody, která tvoří řez z aktuálního rozsahu, který začíná na zadaném indexu. To umožňuje zpracovávat data v Span<T> sadě logických bloků dat, které je možné zpracovat podle potřeby částmi kanálu zpracování dat s minimálním dopadem na výkon. Například vzhledem k tomu, že moderní serverové protokoly jsou často textové, je manipulace s řetězci a podřetězci obzvláště důležitá. Ve třídě String je hlavní metoda pro extrakci podřetězců Substring. Pro datové kanály, které se spoléhají na rozsáhlou manipulaci s řetězci, způsobuje jeho použití určité výkonnostní penalizace, protože:
- Vytvoří nový řetězec pro uložení podřetězce.
- Zkopíruje podmnožinu znaků z původního řetězce do nového řetězce.
Toto přidělení a operaci kopírování lze odstranit použitím buď Span<T>, nebo ReadOnlySpan<T>, jak ukazuje následující příklad.
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
Konstruktory
| Name | Description |
|---|---|
| Span<T>(T) |
Vytvoří novou Span<T> délku 1 kolem zadaného odkazu. |
| Span<T>(T[], Int32, Int32) |
Vytvoří nový Span<T> objekt, který obsahuje zadaný počet prvků pole počínaje zadaným indexem. |
| Span<T>(T[]) |
Vytvoří nový Span<T> objekt po celou dobu zadaného pole. |
| Span<T>(Void*, Int32) |
Vytvoří nový Span<T> objekt ze zadaného |
Vlastnosti
| Name | Description |
|---|---|
| Empty |
Vrátí prázdný Span<T> objekt. |
| IsEmpty |
Vrátí hodnotu, která určuje, jestli je aktuální Span<T> hodnota prázdná. |
| Item[Int32] |
Získá prvek v zadaném indexu založeném na nule. |
| Length |
Vrátí délku aktuálního rozsahu. |
Metody
| Name | Description |
|---|---|
| Clear() |
Vymaže obsah tohoto Span<T> objektu. |
| CopyTo(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 toto Span<T>. |
| GetHashCode() |
Zastaralé.
Vyhodí .NotSupportedException |
| GetPinnableReference() |
Vrátí odkaz na objekt typu T, který lze použít pro připnutí. Tato metoda je určena k podpoře .NET kompilátorů a není určena k zavolání uživatelským kódem. |
| Slice(Int32, Int32) |
Vytvoří řez z aktuálního rozsahu počínaje zadaným indexem pro zadanou délku. |
| Slice(Int32) |
Vytvoří řez z aktuálního rozsahu, který začíná na zadaném indexu. |
| 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í hodnotu 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
| Name | Description |
|---|---|
| Equality(Span<T>, Span<T>) |
Vrátí hodnotu, která určuje, zda jsou dva Span<T> objekty rovny. |
| Implicit(ArraySegment<T> to Span<T>) |
Definuje implicitní převod na ArraySegment<T>Span<T>. |
| Implicit(Span<T> to ReadOnlySpan<T>) |
Definuje implicitní převod na Span<T>ReadOnlySpan<T>. |
| Implicit(T[] to Span<T>) |
Definuje implicitní převod pole na Span<T>. |
| Inequality(Span<T>, Span<T>) |
Vrátí hodnotu, která určuje, zda se dva Span<T> objekty nerovnají. |
Metody rozšíření
| Name | Description |
|---|---|
| BinarySearch<T,TComparable>(Span<T>, TComparable) |
Vyhledá celou seřazenou Span<T> hodnotu pomocí zadaného |
| BinarySearch<T,TComparer>(Span<T>, T, TComparer) |
Vyhledá celou seřazenou Span<T> hodnotu pomocí zadaného |
| BinarySearch<T>(Span<T>, IComparable<T>) |
Vyhledá celou hodnotu seřazenou Span<T> pomocí zadaného IComparable<T> obecného rozhraní. |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
Najde délku jakékoli společné předpony sdílené mezi |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>) |
Najde délku jakékoli společné předpony sdílené mezi |
| Contains<T>(Span<T>, T) |
Určuje, zda je zadaná hodnota nalezena v rozsahu. |
| ContainsAny<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá výskyt některého ze zadaných |
| ContainsAny<T>(Span<T>, SearchValues<T>) |
Vyhledá výskyt některého ze zadaných |
| ContainsAny<T>(Span<T>, T, T, T) |
Vyhledá výskyt parametru |
| ContainsAny<T>(Span<T>, T, T) |
Vyhledá výskyt |
| ContainsAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá zadané rozpětí pro libovolnou jinou hodnotu než zadanou |
| ContainsAnyExcept<T>(Span<T>, SearchValues<T>) |
Vyhledá zadané rozpětí pro libovolnou jinou hodnotu než zadanou |
| ContainsAnyExcept<T>(Span<T>, T, T, T) |
Vyhledá jinou hodnotu než |
| ContainsAnyExcept<T>(Span<T>, T, T) |
Vyhledá v zadaném rozsahu jinou hodnotu než |
| ContainsAnyExcept<T>(Span<T>, T) |
Vyhledá zadané rozpětí pro libovolnou jinou hodnotu než zadanou |
| ContainsAnyExceptInRange<T>(Span<T>, T, T) |
Vyhledá libovolnou hodnotu mimo rozsah mezi |
| ContainsAnyInRange<T>(Span<T>, T, T) |
Vyhledá libovolnou hodnotu v rozsahu mezi |
| Count<T>(Span<T>, ReadOnlySpan<T>) |
Spočítá počet výskytů zadaných |
| Count<T>(Span<T>, T) |
Spočítá počet výskytů zadaných |
| EndsWith<T>(Span<T>, ReadOnlySpan<T>) |
Určuje, zda se zadaná sekvence zobrazí na konci rozsahu. |
| IndexOf<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá zadanou sekvenci a vrátí index prvního výskytu. |
| IndexOf<T>(Span<T>, T) |
Vyhledá zadanou hodnotu a vrátí index prvního výskytu. |
| IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá první index libovolné ze zadaných hodnot. |
| IndexOfAny<T>(Span<T>, SearchValues<T>) |
Vyhledá první index libovolné ze zadaných hodnot. |
| IndexOfAny<T>(Span<T>, T, T, T) |
Vyhledá první index libovolné ze zadaných hodnot. |
| IndexOfAny<T>(Span<T>, T, T) |
Vyhledá první index libovolné ze zadaných hodnot. |
| IndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá první index jakékoli jiné hodnoty, než je zadaná |
| IndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Vyhledá první index jakékoli jiné hodnoty, než je zadaná |
| IndexOfAnyExcept<T>(Span<T>, T, T, T) |
Vyhledá první index jakékoli jiné hodnoty než |
| IndexOfAnyExcept<T>(Span<T>, T, T) |
Vyhledá první index jakékoli jiné hodnoty než dvě zadané hodnoty. |
| IndexOfAnyExcept<T>(Span<T>, T) |
Vyhledá první index jakékoli jiné hodnoty, než je zadaná |
| IndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Vyhledá první index libovolné hodnoty mimo rozsah mezi |
| IndexOfAnyInRange<T>(Span<T>, T, T) |
Vyhledá první index libovolné hodnoty v rozsahu mezi |
| LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá zadanou sekvenci a vrátí index posledního výskytu. |
| LastIndexOf<T>(Span<T>, T) |
Vyhledá zadanou hodnotu a vrátí index posledního výskytu. |
| LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá poslední index libovolné ze zadaných hodnot. |
| LastIndexOfAny<T>(Span<T>, SearchValues<T>) |
Vyhledá poslední index libovolné ze zadaných hodnot. |
| LastIndexOfAny<T>(Span<T>, T, T, T) |
Vyhledá poslední index libovolné ze zadaných hodnot. |
| LastIndexOfAny<T>(Span<T>, T, T) |
Vyhledá poslední index libovolné ze zadaných hodnot. |
| LastIndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Vyhledá poslední index libovolné hodnoty kromě zadané |
| LastIndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Vyhledá poslední index libovolné hodnoty kromě zadané |
| LastIndexOfAnyExcept<T>(Span<T>, T, T, T) |
Vyhledá poslední index jakékoli jiné hodnoty, než je zadaná |
| LastIndexOfAnyExcept<T>(Span<T>, T, T) |
Vyhledá poslední index libovolné hodnoty, která není zadaná |
| LastIndexOfAnyExcept<T>(Span<T>, T) |
Vyhledá poslední index libovolné hodnoty kromě zadané |
| LastIndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Vyhledá poslední index libovolné hodnoty mimo rozsah mezi |
| LastIndexOfAnyInRange<T>(Span<T>, T, T) |
Vyhledá poslední index libovolné hodnoty v rozsahu mezi |
| 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ýstupy posun prvku. |
| Overlaps<T>(Span<T>, ReadOnlySpan<T>) |
Určuje, zda se rozsah a rozsah jen pro čtení překrývají v paměti. |
| Replace<T>(Span<T>, T, T, IEqualityComparer<T>) |
Nahradí všechny výskyty |
| Replace<T>(Span<T>, T, T) |
Nahradí všechny výskyty |
| ReplaceAny<T>(Span<T>, SearchValues<T>, T) |
Nahradí ve |
| ReplaceAnyExcept<T>(Span<T>, SearchValues<T>, T) |
Nahradí ve |
| 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>, IEqualityComparer<T>) |
Určuje, zda jsou dvě sekvence stejné porovnáním prvků pomocí .IEqualityComparer<T> |
| SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) |
Určuje, zda se rozsah a rozsah jen pro čtení rovná porovnáním prvků pomocí IEquatable{T}. Rovná se(T). |
| Sort<T,TComparer>(Span<T>, TComparer) |
Seřadí prvky v celém Span<T> souboru pomocí funkce |
| Sort<T>(Span<T>, Comparison<T>) |
Seřadí prvky v celém Span<T> souboru pomocí zadaného Comparison<T>. |
| Sort<T>(Span<T>) |
Seřadí prvky v celém Span<T> objektu IComparable<T> pomocí implementace každého prvku objektu Span<T>. |
| Sort<TKey,TValue,TComparer>(Span<TKey>, Span<TValue>, TComparer) |
Seřadí dvojici rozsahů (jeden obsahující klíče a druhý obsahující odpovídající položky) na základě klíčů v prvním Span<T> pořadí pomocí zadaného porovnávače. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>, Comparison<TKey>) |
Seřadí dvojici rozsahů (jeden obsahující klíče a druhý obsahující odpovídající položky) na základě klíčů v prvním Span<T> porovnání. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>) |
Seřadí dvojici rozsahů (jeden obsahující klíče a druhý obsahující odpovídající položky) na základě klíčů v prvním Span<T> použití IComparable<T> implementace každého klíče. |
| StartsWith<T>(Span<T>, ReadOnlySpan<T>) |
Určuje, zda se zadaná sekvence zobrazí na začátku rozsahu. |
| ToImmutableArray<T>(Span<T>) |
Převede rozsah na neměnné pole. |
| Trim<T>(Span<T>, ReadOnlySpan<T>) |
Odebere všechny počáteční a koncové výskyty sady prvků zadaných v rozsahu určeném jen pro čtení z rozsahu. |
| Trim<T>(Span<T>, T) |
Odebere všechny počáteční a koncové výskyty zadaného prvku z rozsahu. |
| TrimEnd<T>(Span<T>, ReadOnlySpan<T>) |
Odebere všechny koncové výskyty sady prvků zadaných v rozsahu určeném jen pro čtení z rozsahu. |
| TrimEnd<T>(Span<T>, T) |
Odebere všechny koncové výskyty zadaného prvku z rozsahu. |
| TrimStart<T>(Span<T>, ReadOnlySpan<T>) |
Odebere všechny počáteční výskyty sady prvků zadaných v rozsahu určeném jen pro čtení z rozsahu. |
| TrimStart<T>(Span<T>, T) |
Odebere všechny počáteční výskyty zadaného prvku z rozsahu. |