Span<T> Span<T> Span<T> Span<T> Struct

定義

提供任意記憶體之連續區域的型別和記憶體安全表示。Provides a type- and memory-safe representation of a contiguous region of arbitrary memory.

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

類型參數

T

中的項目類型Span<T>The type of items in the Span<T>.

繼承

備註

Span<T>ref struct配置堆疊上,而不是 managed 堆積上。Span<T> is a ref struct that is allocated on the stack rather than on the managed heap. Ref 結構類型有一些限制,以確保它們無法提升至受控堆積,包括無法 box 處理,他們無法指派給變數的型別Objectdynamic成任何介面類型,也不能是中的欄位參考型別,而且它們不能跨awaityield界限。Ref struct types have a number of restrictions to ensure that they cannot be promoted to the managed heap, including that they can't be boxed, they can't be assigned to variables of type Object, dynamic or to any interface type, they can't be fields in a reference type, and they can't be used across await and yield boundaries. 此外,兩個方法,會呼叫Equals(Object)GetHashCode,會擲回NotSupportedExceptionIn addition, calls to two methods, Equals(Object) and GetHashCode, throw a NotSupportedException.

重要

因為它是僅限堆疊的型別,Span<T>不適合許多情況下,需要儲存在堆積上的緩衝區的參考。Because it is a stack-only type, Span<T> is unsuitable for many scenarios that require storing references to buffers on the heap. 這是如此,比方說,讓非同步方法呼叫的常式。This is true, for example, of routines that make asynchronous method calls. 對於這類情況中,您可以使用的補充System.Memory<T>System.ReadOnlyMemory<T>型別。For such scenarios, you can use the complementary System.Memory<T> and System.ReadOnlyMemory<T> types.

代表不可變或唯讀結構的 span,對於使用System.ReadOnlySpan<T>For spans that represent immutable or read-only structures, use System.ReadOnlySpan<T>.

範圍<T > 和記憶體Span<T> and memory

ASpan<T>代表任意記憶體中的連續區域。A Span<T> represents a contiguous region of arbitrary memory. ASpan<T>執行個體通常用來保存的項目陣列的一部分。A Span<T> instance is often used to hold the elements of an array or a portion of an array. 不同於陣列,不過,Span<T>執行個體可以指向受管理的記憶體,原生記憶體,或在受管理的記憶體堆疊。Unlike an array, however, a Span<T> instance can point to managed memory, native memory, or memory managed on the stack. 下列範例會建立Span<Byte>從陣列:The following example creates a Span<Byte> from an array:

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

下列範例會建立Span<Byte>從 100 個位元組的原生記憶體:The following example creates a Span<Byte> from 100 bytes of native memory:

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

下列範例會使用C# stackalloc關鍵字可配置的記憶體堆疊上的 100 個位元組:The following example uses the C# stackalloc keyword to allocate 100 bytes of memory on the stack:

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

因為Span<T>是任意的記憶體區塊,方法的抽象概念Span<T>類別和方法Span<T>參數對任何Span<T>物件,不論其封裝的記憶體的類型。Because Span<T> is an abstraction over an arbitrary block of memory, methods of the Span<T> class and methods with Span<T> parameters operate on any Span<T> object regardless of the kind of memory it encapsulates. 例如,每個程式碼中的個別區段,用來初始化範圍及計算其項目的總和可以變更為單一的初始設定和計算方法,如下列範例說明:For example, each of the separate sections of code that initialize the span and calculate the sum of its elements can be changed into single initialization and calculation methods, as the following example illustrates:

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(arraySpan):N0}");    
    
    Marshal.FreeHGlobal(native);

    // Create a span on the stack.
    Span<byte> stackSpan = stackalloc byte[100];

    InitializeSpan(stackSpan);
    Console.WriteLine($"The sum is {ComputeSum(arraySpan):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

範圍<T > 和陣列Span<T> and arrays

它會包裝在陣列中,當Span<T>可以包裝整個陣列中的範例中所顯示的一樣範圍<T > 和記憶體區段。When it wraps an array, Span<T> can wrap an entire array, as it did in the examples in the Span<T> and memory section. 因為它支援切割,Span<T>也可以指向任何陣列中的連續範圍。Because it supports slicing, Span<T> can also point to any contiguous range within the array.

下列範例會建立 10 個元素的整數陣列的中間的五個項目之配量。The following example creates a slice of the middle five elements of a 10-element integer array. 請注意程式碼會加倍的配量中的每個整數值。Note that the code doubles the values of each integer in the slice. 如輸出所示,範圍所做的變更會反映在陣列的值。As the output shows, the changes made by the span are reflected in the values of the array.

using System;

namespace span
{
    class Program
    {
        static void Main(string[] args)
        {
            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

範圍<T > 和配量Span<T> and slices

Span<T> 包含兩個多載Slice形成配量超出指定的索引開始的目前範圍的方法。Span<T> includes two overloads of the Slice method that form a slice out of the current span that starts at a specified index. 如此可讓您將在資料Span<T>做為一組可處理視資料處理管線,其中含有最少的效能影響的部分邏輯區塊。This makes it possible to treat the data in a Span<T> as a set of logical chunks that can be processed as needed by portions of a data processing pipeline with minimal performance impact. 例如,由於新式伺服器通訊協定通常是以文字為基礎,操作字串和子字串是特別重要。For example, since modern server protocols are often text-based, manipulation of strings and substrings is particularly important. String類別的主要方法擷取子字串是SubstringIn the String class, the major method for extracting substrings is Substring. 針對依賴廣泛的字串操作的資料管線,其使用會提供一些效能的負面影響,因為它:For data pipelines that rely on extensive string manipulation, its use offers some performance penalties, since it:

  1. 建立新的字串,用來保存子字串。Creates a new string to hold the substring.

  2. 原始字串一部分的字元複製到新的字串。Copies a subset of the characters from the original string to the new string.

要消除這項配置和複製作業,請使用Span<T>ReadOnlySpan<T>,如下列範例所示:This allocation and copy operation can be eliminated by using either Span<T> or ReadOnlySpan<T>, as the following example shows:

using System;

class Program
{
    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

建構函式

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

在整個指定的陣列上建立新的 Span<T> 物件。Creates a new Span<T> object over the entirety of a specified array.

Span<T>(Void*, Int32) Span<T>(Void*, Int32) Span<T>(Void*, Int32) Span<T>(Void*, Int32)

透過指定的 T 元素數目建立新 Span<T> 物件,從指定的記憶體位址開始。Creates a new Span<T> object from a specified number of T elements starting at a specified memory address.

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

建立新的 Span<T> 物件,其中包含起始於指定索引之陣列的指定項目數。Creates a new Span<T> object that includes a specified number of elements of an array starting at a specified index.

屬性

Empty Empty Empty Empty

傳回空的 Span<T> 物件。Returns an empty Span<T> object.

IsEmpty IsEmpty IsEmpty IsEmpty

傳回值,指出目前的 Span<T> 是否為空白。Returns a value that indicates whether the current Span<T> is empty.

Item[Range] Item[Range] Item[Range] Item[Range]
Item[Int32] Item[Int32] Item[Int32] Item[Int32]

取得位於指定索引的元素,該索引以零起始。Gets the element at the specified zero-based index.

Item[Index] Item[Index] Item[Index] Item[Index]
Length Length Length Length

傳回目前範圍的長度。Returns the length of the current span.

方法

Clear() Clear() Clear() Clear()

清除這個 Span<T> 物件的內容。Clears the contents of this Span<T> object.

CopyTo(Span<T>) CopyTo(Span<T>) CopyTo(Span<T>) CopyTo(Span<T>)

將這個 Span<T> 的內容複製到目的地 Span<T>Copies the contents of this Span<T> into a destination Span<T>.

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

不支援呼叫這個方法。Calls to this method are not supported.

Fill(T) Fill(T) Fill(T) Fill(T)

以指定的值填入這個範圍的項目。Fills the elements of this span with a specified value.

GetEnumerator() GetEnumerator() GetEnumerator() GetEnumerator()

傳回這個 Span<T> 的列舉值。Returns an enumerator for this Span<T>.

GetHashCode() GetHashCode() GetHashCode() GetHashCode()

擲回 NotSupportedExceptionThrows a NotSupportedException.

GetPinnableReference() GetPinnableReference() GetPinnableReference() GetPinnableReference()

傳回索引位置為零之 Span<T> 的項目參考。Returns a reference to the element of the Span<T> at index zero.

Slice(Index) Slice(Index) Slice(Index) Slice(Index)
Slice(Int32) Slice(Int32) Slice(Int32) Slice(Int32)

從起始於指定索引的目前範圍形成配量。Forms a slice out of the current span that begins at a specified index.

Slice(Range) Slice(Range) Slice(Range) Slice(Range)
Slice(Int32, Int32) Slice(Int32, Int32) Slice(Int32, Int32) Slice(Int32, Int32)

從起始於指定索引之指定長度的目前範圍形成配量。Forms a slice out of the current span starting at a specified index for a specified length.

ToArray() ToArray() ToArray() ToArray()

將這個範圍的內容複製到新的陣列。Copies the contents of this span into a new array.

ToString() ToString() ToString() ToString()

傳回此 Span<T> 物件的字串表示。Returns the string representation of this Span<T> object.

TryCopyTo(Span<T>) TryCopyTo(Span<T>) TryCopyTo(Span<T>) TryCopyTo(Span<T>)

嘗試將目前的 Span<T> 複製到目的地 Span<T>,並傳回值,指出複製作業是否成功。Attempts to copy the current Span<T> to a destination Span<T> and returns a value that indicates whether the copy operation succeeded.

運算子

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

傳回值,指出兩個 Span<T> 物件是否相等。Returns a value that indicates whether two Span<T> objects are equal.

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

定義從 ArraySegment<T>Span<T> 的隱含轉換。Defines an implicit conversion of an ArraySegment<T> to a Span<T>.

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

定義從 Span<T>ReadOnlySpan<T> 的隱含轉換。Defines an implicit conversion of a Span<T> to a ReadOnlySpan<T>.

Implicit(T[] to Span<T>) Implicit(T[] to Span<T>) Implicit(T[] to Span<T>) Implicit(T[] to Span<T>)

定義從陣列到 Span<T> 的隱含轉換。Defines an implicit conversion of an array to a Span<T>.

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

傳回值,指出兩個 Span<T> 物件是否不相等。Returns a value that indicates whether two Span<T> objects are not equal.

Extension Methods

BinarySearch<T>(Span<T>, IComparable<T>) BinarySearch<T>(Span<T>, IComparable<T>) BinarySearch<T>(Span<T>, IComparable<T>) BinarySearch<T>(Span<T>, IComparable<T>)
BinarySearch<T,TComparer>(Span<T>, T, TComparer) BinarySearch<T,TComparer>(Span<T>, T, TComparer) BinarySearch<T,TComparer>(Span<T>, T, TComparer) BinarySearch<T,TComparer>(Span<T>, T, TComparer)
BinarySearch<T,TComparable>(Span<T>, TComparable) BinarySearch<T,TComparable>(Span<T>, TComparable) BinarySearch<T,TComparable>(Span<T>, TComparable) BinarySearch<T,TComparable>(Span<T>, TComparable)
EndsWith<T>(Span<T>, ReadOnlySpan<T>) EndsWith<T>(Span<T>, ReadOnlySpan<T>) EndsWith<T>(Span<T>, ReadOnlySpan<T>) EndsWith<T>(Span<T>, ReadOnlySpan<T>)
IndexOf<T>(Span<T>, T) IndexOf<T>(Span<T>, T) IndexOf<T>(Span<T>, T) IndexOf<T>(Span<T>, T)
IndexOf<T>(Span<T>, ReadOnlySpan<T>) IndexOf<T>(Span<T>, ReadOnlySpan<T>) IndexOf<T>(Span<T>, ReadOnlySpan<T>) IndexOf<T>(Span<T>, ReadOnlySpan<T>)
IndexOfAny<T>(Span<T>, T, T) IndexOfAny<T>(Span<T>, T, T) IndexOfAny<T>(Span<T>, T, T) IndexOfAny<T>(Span<T>, T, T)
IndexOfAny<T>(Span<T>, T, T, T) IndexOfAny<T>(Span<T>, T, T, T) IndexOfAny<T>(Span<T>, T, T, T) IndexOfAny<T>(Span<T>, T, T, T)
IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) IndexOfAny<T>(Span<T>, ReadOnlySpan<T>)
LastIndexOf<T>(Span<T>, T) LastIndexOf<T>(Span<T>, T) LastIndexOf<T>(Span<T>, T) LastIndexOf<T>(Span<T>, T)
LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) LastIndexOf<T>(Span<T>, ReadOnlySpan<T>)
LastIndexOfAny<T>(Span<T>, T, T) LastIndexOfAny<T>(Span<T>, T, T) LastIndexOfAny<T>(Span<T>, T, T) LastIndexOfAny<T>(Span<T>, T, T)
LastIndexOfAny<T>(Span<T>, T, T, T) LastIndexOfAny<T>(Span<T>, T, T, T) LastIndexOfAny<T>(Span<T>, T, T, T) LastIndexOfAny<T>(Span<T>, T, T, T)
LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>)
Overlaps<T>(Span<T>, ReadOnlySpan<T>) Overlaps<T>(Span<T>, ReadOnlySpan<T>) Overlaps<T>(Span<T>, ReadOnlySpan<T>) Overlaps<T>(Span<T>, ReadOnlySpan<T>)
Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32)
Reverse<T>(Span<T>) Reverse<T>(Span<T>) Reverse<T>(Span<T>) Reverse<T>(Span<T>)
SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>) SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>) SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>) SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>)
SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) SequenceEqual<T>(Span<T>, ReadOnlySpan<T>)
StartsWith<T>(Span<T>, ReadOnlySpan<T>) StartsWith<T>(Span<T>, ReadOnlySpan<T>) StartsWith<T>(Span<T>, ReadOnlySpan<T>) StartsWith<T>(Span<T>, ReadOnlySpan<T>)

適用於