Span<T> 結構

定義

提供任意記憶體之連續區域的型別和記憶體安全表示。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

@No__t-0 中的專案類型。The type of items in the Span<T>.

繼承
Span<T>

備註

Span<T> 是在堆疊上配置的ref 結構,而不是在 managed 堆積上。Span<T> is a ref struct that is allocated on the stack rather than on the managed heap. Ref 結構類型有一些限制,以確保無法將它們升級為受控堆積,包括無法進行裝箱、無法將它們指派給類型 Object 的變數、dynamic 或任何介面類別型,它們不能是參考型別中的欄位和它們無法跨 await 和 @no__t 3 界限使用。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.

如果是代表不可變或唯讀結構的範圍,請使用 System.ReadOnlySpan<T>For spans that represent immutable or read-only structures, use System.ReadOnlySpan<T>.

Span @ no__t-0T > 和記憶體Span<T> and memory

@No__t-0 代表任意記憶體的連續區域。A Span<T> represents a contiguous region of arbitrary memory. @No__t-0 實例通常用來保存陣列的元素或陣列的一部分。A Span<T> instance is often used to hold the elements of an array or a portion of an array. 不過,與陣列不同的是,@no__t 0 實例可以指向 managed 記憶體、原生記憶體或堆疊上管理的記憶體。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

下列範例會從100位元組的原生記憶體建立 Span<Byte>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> 是對任意記憶體區塊的抽象概念,所以不論其封裝的記憶體種類為何,@no__t 1 類別的方法和具有 @no__t 2 參數的方法都會在任何 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(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

Span @ no__t-0T > 和陣列Span<T> and arrays

當它包裝陣列時,Span<T> 可以包裝整個陣列,如同在Span @ no__t-2T > 和 memory一節的範例中所做的一樣。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

Span @ no__t-0T > 和配量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> 物件。Creates a new Span<T> object over the entirety of a specified array.

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.

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.

屬性

Empty

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

IsEmpty

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

Item[Int32]

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

Length

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

方法

Clear()

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

CopyTo(Span<T>)

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

Equals(Object)

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

Fill(T)

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

GetEnumerator()

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

GetHashCode()

擲回 NotSupportedExceptionThrows a NotSupportedException.

GetPinnableReference()

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

Slice(Int32)

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

Slice(Int32, Int32)

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

ToArray()

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

ToString()

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

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

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

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

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

Implicit(T[] to Span<T>)

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

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

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

擴充方法

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

使用指定的 IComparable<T> 泛型介面,在整個已排序的 Span<T> 中搜尋值。Searches an entire sorted Span<T> for a value using the specified IComparable<T> generic interface.

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

使用指定的 TComparer 泛型型別,在整個已排序的 Span<T> 中搜尋指定的值。Searches an entire sorted Span<T> for a specified value using the specified TComparer generic type.

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

使用指定的 TComparable 泛型型別,在整個已排序的 Span<T> 中搜尋值。Searches an entire sorted Span<T> for a value using the specified TComparable generic type.

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

指出是否在範圍中找到指定的值。Indicates whether a specified value is found in a span. 值是使用 IEquatable{T}.Equals(T) 來進行比較。Values are compared using IEquatable{T}.Equals(T).

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

判斷所指定序列是否出現在範圍的結尾。Determines whether the specified sequence appears at the end of a span.

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

搜尋指定的值,並傳回第一個出現位置的索引。Searches for the specified value and returns the index of its first occurrence. 值是使用 IEquatable{T}.Equals(T) 來進行比較。Values are compared using IEquatable{T}.Equals(T).

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

搜尋指定的序列,並傳回第一個出現位置的索引。Searches for the specified sequence and returns the index of its first occurrence. 值是使用 IEquatable{T}.Equals(T) 來進行比較。Values are compared using IEquatable{T}.Equals(T).

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

搜尋任何指定值的第一個索引,類似於使用邏輯 OR 運算子呼叫 IndexOf 多次。Searches for the first index of any of the specified values similar to calling IndexOf several times with the logical OR operator.

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

搜尋任何指定值的第一個索引,類似於使用邏輯 OR 運算子呼叫 IndexOf 多次。Searches for the first index of any of the specified values similar to calling IndexOf several times with the logical OR operator.

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

搜尋任何指定值的第一個索引,類似於使用邏輯 OR 運算子呼叫 IndexOf 多次。Searches for the first index of any of the specified values similar to calling IndexOf several times with the logical OR operator.

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

搜尋指定的值,並傳回最後一個出現位置的索引。Searches for the specified value and returns the index of its last occurrence. 值是使用 IEquatable{T}.Equals(T) 來進行比較。Values are compared using IEquatable{T}.Equals(T).

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

搜尋指定的序列,並傳回最後一個出現位置的索引。Searches for the specified sequence and returns the index of its last occurrence. 值是使用 IEquatable{T}.Equals(T) 來進行比較。Values are compared using IEquatable{T}.Equals(T).

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

搜尋任何指定值的最後一個索引,類似於使用邏輯 OR 運算子呼叫 LastIndexOf 多次。Searches for the last index of any of the specified values similar to calling LastIndexOf several times with the logical OR operator.

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

搜尋任何指定值的最後一個索引,類似於使用邏輯 OR 運算子呼叫 LastIndexOf 多次。Searches for the last index of any of the specified values similar to calling LastIndexOf several times with the logical OR operator.

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

搜尋任何指定值的最後一個索引,類似於使用邏輯 OR 運算子呼叫 LastIndexOf 多次。Searches for the last index of any of the specified values similar to calling LastIndexOf several times with the logical OR operator.

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

判斷一個範圍和一個唯讀範圍在記憶體中是否重疊。Determines whether a span and a read-only span overlap in memory.

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

判斷一個範圍和一個唯讀範圍在記憶體中是否重疊,並輸出元素位移。Determines whether a span and a read-only span overlap in memory and outputs the element offset.

Reverse<T>(Span<T>)

反轉整個範圍中的元素順序。Reverses the sequence of the elements in the entire span.

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

使用 IComparable{T}.CompareTo(T) 來比較元素,判斷一個範圍和一個唯讀範圍的相對順序。Determines the relative order of a span and a read-only span by comparing the elements using IComparable{T}.CompareTo(T).

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

使用 IEquatable{T}.Equals(T) 來比較元素,判斷一個範圍和一個唯讀範圍是否相等。Determines whether a span and a read-only span are equal by comparing the elements using IEquatable{T}.Equals(T).

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

判斷所指定序列是否出現在範圍的開頭。Determines whether a specified sequence appears at the start of a span.

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

從範圍中移除所有開頭和尾端指定元素項目。Removes all leading and trailing occurrences of a specified element from a span.

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

從範圍中移除唯讀範圍中指定的所有開頭和尾端元素集項目。Removes all leading and trailing occurrences of a set of elements specified in a read-only span from a span.

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

從範圍中移除所有尾端指定元素項目。Removes all trailing occurrences of a specified element from a span.

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

從範圍中移除唯讀範圍中指定的所有尾端元素集項目。Removes all trailing occurrences of a set of elements specified in a read-only span from a span.

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

從範圍中移除所有開頭指定元素項目。Removes all leading occurrences of a specified element from the span.

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

從範圍中移除唯讀範圍中指定的所有開頭元素集項目。Removes all leading occurrences of a set of elements specified in a read-only span from the span.

適用於