Span<T> 構造体

定義

任意のメモリの連続した領域のタイプ セーフでメモリ セーフな表現を提供します。

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)

型パラメーター

T

Span<T>内の項目の種類。

継承
Span<T>
属性

注釈

Span<T>型は、マネージド ヒープではなくスタックに割り当てられる ref 構造体です。 Ref 構造体型には、マネージド ヒープに昇格できないようにするためのいくつかの制限があります。これには、次のような制限があります。

  • 箱入り。
  • Object型またはdynamic型の変数、またはインターフェイスの入力ミスに割り当てられます。
  • 参照型のフィールド。
  • awaityieldの境界を越えて使用されます。

さらに、Equals(Object)GetHashCodeの2つのメソッドをコールすると、NotSupportedExceptionをスローします。

Important

Span<T>はスタック専用の型であるため、ヒープ上でバッファーへの参照を格納する必要のある、多くのシナリオには適していません。 たとえば、非同期メソッドの呼び出しを行うルーチンなどが当てはまります。 このようなシナリオでは、補完的なSystem.Memory<T>System.ReadOnlyMemory<T>型を使用できます。

不変、または読み取り専用の構造を表すスパンの場合、System.ReadOnlySpan<T>を使用してください。

メモリ

Span<T>は任意のメモリの連続した領域を表します。 Span<T>インスタンスは、配列の要素または配列の一部を保持するためによく使用されます。 ただし、配列とは異なり、Span<T>インスタンスは、マネージド メモリ、ネイティブ メモリ、スタック上で管理されたメモリを指すことができます。 次の例では、配列からSpan<Byte>を作成します。

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

次の例では、ネイティブ メモリの 100 バイトからSpan<Byte>を作成します。

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

次の例では、 C#のstackallocキーワードを用いて、スタック上に 100 バイトのメモリを割り当てます。

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

Span<T>は任意のメモリ ブロックに対する抽象化であるため、Span<T>型のメソッドとSpan<T> パラメーターを持つメソッドは、カプセル化するメモリの種類に関係なく、任意のSpan<T> オブジェクトで動作します。 たとえば、次の例に示すように、スパンを初期化し、要素の合計を計算する個別のコード セクションをそれぞれ、単一の初期化メソッドと計算メソッドにリファクタリングできます。

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

配列

配列をラップする場合、 Span<T> は、 Memory セクションの例のように、配列全体をラップできます。 スライスがサポートされているため、 Span<T> は配列内の任意の連続した範囲を指すこともできます。

次の例では、10 要素ある整数配列の中間 5 つの要素のスライスを作成します。 コードがスライス内の各整数の値を 2 倍することに注意してください。 出力のとおり、スパンで加えられた変更は、配列の値に反映されます。

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

スライス

Span<T>には、現在のスパンより、指定したインデックスから始まるスライスを形成するSliceメソッドの 2 つのオーバー ロードが含まれています。 これにより、Span<T>のデータを、パフォーマンスの影響を最小限にしながら、データ処理パイプラインの一部で必要に応じて処理できる、一連の論理的なまとまりとして扱うことができます。 たとえば、最新のサーバー プロトコルは多くの場合、テキスト ベースであるため、文字列と部分文字列の操作は特に重要です。 Stringクラスの場合、部分文字列の抽出に使う主要なメソッドはSubstringです。 広範な文字列操作に依存するデータ パイプラインは、次のように、いくつかのパフォーマンスの低下を招きます。

  1. 部分文字列を保持する新しい文字列を作成します。
  2. 元の文字列から新しい文字列に文字のサブセットをコピーします。

次の例に示すように、この割り当てとコピー操作は、Span<T>またはReadOnlySpan<T>いずれかを使用して削除できます。

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

コンストラクター

名前 説明
Span<T>(T)

指定した参照の周囲に長さ 1 の新しい Span<T> を作成します。

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

指定したインデックスから始まる配列の指定した数の要素を含む新しい Span<T> オブジェクトを作成します。

Span<T>(T[])

指定した配列全体にわたって新しい Span<T> オブジェクトを作成します。

Span<T>(Void*, Int32)

指定したメモリ アドレスから始まる、指定した数のSpan<T>要素から新しいT オブジェクトを作成します。

プロパティ

名前 説明
Empty

空の Span<T> オブジェクトを返します。

IsEmpty

現在の Span<T> が空かどうかを示す値を返します。

Item[Int32]

指定した 0 から始まるインデックス位置にある要素を取得します。

Length

現在のスパンの長さを返します。

メソッド

名前 説明
Clear()

この Span<T> オブジェクトの内容をクリアします。

CopyTo(Span<T>)

この Span<T> の内容をコピー先の Span<T>にコピーします。

Equals(Object)
古い.
古い.

このメソッドの呼び出しはサポートされていません。

Fill(T)

このスパンの要素に指定した値を入力します。

GetEnumerator()

この Span<T>の列挙子を返します。

GetHashCode()
古い.

NotSupportedException をスローします。

GetPinnableReference()

ピン留めに使用できる T 型のオブジェクトへの参照を返します。

このメソッドは、.NET コンパイラをサポートすることを目的としており、ユーザー コードによって呼び出されるものではありません。

Slice(Int32, Int32)

指定した長さの指定したインデックスから始まる、現在のスパンからスライスを形成します。

Slice(Int32)

指定したインデックスから始まる現在のスパンからスライスを形成します。

ToArray()

このスパンの内容を新しい配列にコピーします。

ToString()

この Span<T> オブジェクトの文字列形式を返します。

TryCopyTo(Span<T>)

現在の Span<T> をコピー先の Span<T> にコピーしようとし、コピー操作が成功したかどうかを示す値を返します。

演算子

名前 説明
Equality(Span<T>, Span<T>)

2 つの Span<T> オブジェクトが等しいかどうかを示す値を返します。

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

ArraySegment<T>からSpan<T>への暗黙的な変換を定義します。

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

Span<T>からReadOnlySpan<T>への暗黙的な変換を定義します。

Implicit(T[] to Span<T>)

配列から Span<T>への暗黙的な変換を定義します。

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

2 つの Span<T> オブジェクトが等しくないかどうかを示す値を返します。

拡張メソッド

名前 説明
BinarySearch<T,TComparable>(Span<T>, TComparable)

指定したSpan<T>ジェネリック型を使用して、並べ替えられたTComparable全体で値を検索します。

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

指定したSpan<T>ジェネリック型を使用して、並べ替えられたTComparer全体で指定した値を検索します。

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

指定したSpan<T>ジェネリック インターフェイスを使用して、並べ替えられたIComparable<T>全体で値を検索します。

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

spanotherの間で共有される共通プレフィックスの長さを検索します。

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

spanotherの間で共有される共通プレフィックスの長さを検索します。

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

指定した値がスパン内に見つかったかどうかを示します。

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

指定した values のいずれかが出現する箇所を検索し、見つかった場合は true 返します。 見つからない場合は、 falseを返します。

ContainsAny<T>(Span<T>, SearchValues<T>)

指定した values のいずれかが出現する箇所を検索し、見つかった場合は true 返します。 見つからない場合は、 falseを返します。

ContainsAny<T>(Span<T>, T, T, T)

指定したスパン内の value0value1、または value2 の出現箇所を検索します。

ContainsAny<T>(Span<T>, T, T)

value0またはvalue1の出現箇所を検索し、見つかった場合はtrueを返します。 見つからない場合は、 falseを返します。

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

指定したスパンで、指定した values以外の値を検索します。

ContainsAnyExcept<T>(Span<T>, SearchValues<T>)

指定したスパンで、指定した values以外の値を検索します。

ContainsAnyExcept<T>(Span<T>, T, T, T)

value0value1、またはvalue2以外の値を検索します。

ContainsAnyExcept<T>(Span<T>, T, T)

指定したスパンで、 value0 または value1以外の値を検索します。

ContainsAnyExcept<T>(Span<T>, T)

指定したスパンで、指定した value以外の値を検索します。

ContainsAnyExceptInRange<T>(Span<T>, T, T)

lowInclusivehighInclusiveの間の範囲外の値 (両端を含む) を検索します。

ContainsAnyInRange<T>(Span<T>, T, T)

lowInclusivehighInclusiveの範囲内の任意の値を検索し、見つかった場合はtrueを返します。 見つからない場合は、 falseを返します。

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

指定した valuespanで発生した回数をカウントします。

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

指定した valuespanで発生した回数をカウントします。

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

指定したシーケンスがスパンの末尾に表示されるかどうかを判断します。

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

指定したシーケンスを検索し、最初に出現するインデックスを返します。

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

指定した値を検索し、最初に出現するインデックスを返します。

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

指定した値の最初のインデックスを検索します。

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

指定した値の最初のインデックスを検索します。

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

指定した値の最初のインデックスを検索します。

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

指定した値の最初のインデックスを検索します。

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

指定した values以外の値の最初のインデックスを検索します。

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

指定した values以外の値の最初のインデックスを検索します。

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

value0value1、またはvalue2以外の値の最初のインデックスを検索します。

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

指定した 2 つの値以外の値の最初のインデックスを検索します。

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

指定した value以外の値の最初のインデックスを検索します。

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

lowInclusiveからhighInclusiveまでの範囲を含む、値の最初のインデックスを検索します。

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

lowInclusiveからhighInclusiveまでの範囲の任意の値の最初のインデックスを検索します(両端を含む)。

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

指定したシーケンスを検索し、最後に出現したシーケンスのインデックスを返します。

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

指定した値を検索し、最後に出現したインデックスを返します。

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

指定した値の最後のインデックスを検索します。

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

指定した値の最後のインデックスを検索します。

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

指定した値の最後のインデックスを検索します。

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

指定した値の最後のインデックスを検索します。

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

指定した values以外の値の最後のインデックスを検索します。

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

指定した values以外の値の最後のインデックスを検索します。

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

指定した value0value1、または value2以外の値の最後のインデックスを検索します。

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

指定した value0 または value1以外の値の最後のインデックスを検索します。

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

指定した value以外の値の最後のインデックスを検索します。

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

lowInclusiveから highInclusive までの範囲を含む値の最後のインデックスを検索します。

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

lowInclusiveからhighInclusiveまでの範囲の値の最後のインデックスを検索します。値を含みます。

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

スパンと読み取り専用スパンがメモリ内で重複しているかどうかを判断し、要素のオフセットを出力します。

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

スパンと読み取り専用スパンがメモリ内で重複するかどうかを決定します。

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

出現するすべての oldValuenewValue で置き換えます。

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

出現するすべての oldValuenewValue で置き換えます。

ReplaceAny<T>(Span<T>, SearchValues<T>, T)

span values内のすべての要素をnewValueに置き換えます。

ReplaceAnyExcept<T>(Span<T>, SearchValues<T>, T)

span values内の要素以外のすべての要素をnewValueに置き換えます。

Reverse<T>(Span<T>)

スパン全体の要素のシーケンスを反転します。

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

IComparable{T} を使用して要素を比較することで、スパンと読み取り専用スパンの相対順序を決定します。CompareTo(T)。

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

IEqualityComparer<T>を使用して要素を比較することで、2 つのシーケンスが等しいかどうかを判断します。

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

IEquatable{T} を使用して要素を比較することで、スパンと読み取り専用スパンが等しいかどうかを判断します。Equals(T)。

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

Span<T>を使用して、TComparer全体の要素を並べ替えます。

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

指定したSpan<T>を使用して、Comparison<T>全体の要素を並べ替えます。

Sort<T>(Span<T>)

Span<T>の各要素のIComparable<T>実装を使用して、Span<T>全体の要素を並べ替えます。

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

指定した比較子を使用して、最初の Span<T> のキーに基づいてスパンのペア (1 つはキーを含み、もう 1 つは対応する項目を含む) を並べ替えます。

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

指定した比較を使用して、最初の Span<T> のキーに基づいてスパンのペア (1 つはキーを含み、もう 1 つは対応する項目を含む) を並べ替えます。

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

各キーのSpan<T>実装を使用して、最初のIComparable<T>のキーに基づいてスパンのペア (1 つはキーを含み、もう 1 つは対応する項目を含む) を並べ替えます。

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

指定したシーケンスがスパンの先頭に表示されるかどうかを判断します。

ToImmutableArray<T>(Span<T>)

スパンを変更できない配列に変換します。

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

スパンから、読み取り専用スパンで指定された要素のセットの先頭と末尾のすべての出現箇所を削除します。

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

指定した要素の先頭と末尾のすべての出現箇所をスパンから削除します。

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

読み取り専用スパンで指定された一連の要素の後続の出現をすべてスパンから削除します。

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

指定した要素の末尾のすべての出現箇所をスパンから削除します。

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

読み取り専用スパンで指定された要素セットの先頭のすべての出現箇所をスパンから削除します。

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

指定した要素の先頭のすべての出現箇所をスパンから削除します。

適用対象

こちらもご覧ください