Span<T> Структура

Определение

Предоставляет типобезопасную и безопасную для памяти реализацию непрерывной области произвольной памяти.

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

Параметры типа

T

Тип элементов в Span<T> .

Наследование
Span<T>

Комментарии

Span<T> — Это структура ссылки , которая выделяется в стеке, а не в управляемой куче. Типы структур ref имеют ряд ограничений, чтобы гарантировать, что их нельзя повысить до управляемой кучи, в том числе что они не могут быть упакованы, они не могут быть назначены переменным типа Object dynamic или любому типу интерфейса, они не могут быть полями в ссылочном типе и не могут использоваться в await и в yield границах. Кроме того, вызовы двух методов Equals(Object) и GetHashCode вызывают исключение NotSupportedException .

Важно!

Поскольку это тип, предназначенный только для стека, Span<T> не подходит для многих сценариев, требующих хранения ссылок на буферы в куче. Это верно, например, для подпрограмм, которые выполняют асинхронные вызовы методов. В таких случаях можно использовать дополняющие System.Memory<T> System.ReadOnlyMemory<T> типы и.

Для диапазонов, которые представляют структуры, которые являются неизменяемыми или доступны только для чтения, используйте System.ReadOnlySpan<T> .

Диапазон <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

В следующем примере создается Span<Byte> от 100 байт собственной памяти:

// 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 байт памяти в стеке:

// 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> объектом независимо от типа памяти, которую он инкапсулирует. Например, каждый из отдельных разделов кода, которые инициализируют диапазон и вычисляют сумму его элементов, можно изменить в отдельные методы инициализации и вычисления, как показано в следующем примере:

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

Диапазон <T> и массивы

При создании оболочки Span<T> для массива может переносить весь массив, как в примерах в разделе Span <T> и Memory . Так как он поддерживает срезы, Span<T> может также указывать на любой непрерывный диапазон в массиве.

В следующем примере создается срез средних пяти элементов массива целых чисел из 10 элементов. Обратите внимание, что код удваивает значения каждого целого числа в срезе. Как видно из выходных данных, изменения, внесенные диапазоном, отражаются в значениях массива.

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> содержит две перегрузки Slice метода, образующих срез из текущего диапазона, который начинается с указанного индекса. Это позволяет обрабатывать данные в Span<T> как набор логических блоков, которые могут обрабатываться по мере необходимости в частях конвейера обработки данных с минимальным влиянием на производительность. Например, так как современные серверные протоколы часто являются текстовыми, особенно важно манипулировать строками и подстроками. В String классе основной метод извлечения подстрок — Substring . Для конвейеров данных, которые используют обширную обработку строк, ее использование обеспечивает некоторые снижения производительности, поскольку:

  1. Создает новую строку для хранения подстроки.

  2. Копирует подмножество символов из исходной строки в новую строку.

Эту операцию выделения и копирования можно исключить с помощью Span<T> или ReadOnlySpan<T> , как показано в следующем примере:

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> по всему указанному массиву.

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

Создает новый объект Span<T>, который включает указанное число элементов массива, начиная с указанного индекса.

Span<T>(Void*, Int32)

Создает объект Span<T> из указанного числа элементов T, начиная с заданного адреса памяти.

Свойства

Empty

Возвращает пустой объект Span<T>.

IsEmpty

Возвращает значение, указывающее, пуст ли текущий объект Span<T>.

Item[Int32]

Возвращает элемент по указанному индексу, начинающемуся с нуля.

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)

Формирует срез вне текущего диапазона, который начинается с указанного индекса.

Slice(Int32, Int32)

Формирует срез вне текущей области, начиная с указанного индекса до указанной длины.

ToArray()

Копирует содержимое этого диапазона в новый массив.

ToString()

Возвращает строковое представление конкретного объекта Span<T>.

TryCopyTo(Span<T>)

Пытается скопировать текущий Span<T> в назначение Span<T> и возвращает значение, указывающее, успешно ли выполнена операция копирования.

Операторы

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

Возвращает значение, указывающее, равны ли два объекта 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>)

Возвращает значение, указывающее, являются ли два объекта Span<T> неравными.

Методы расширения

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

Выполняет поиск значения во всем отсортированном массиве Span<T>, используя заданный универсальный интерфейс IComparable<T>.

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

Выполняет поиск указанного значения во всем отсортированном массиве Span<T>, используя заданный универсальный тип TComparer.

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

Выполняет поиск значения во всем отсортированном массиве Span<T>, используя заданный универсальный тип TComparable.

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

Указывает, найдено ли указанное значение в диапазоне. Значения сравниваются с помощью IEquatable {T}.Equals (T).

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

Определяет, отображается ли указанная последовательность в конце диапазона.

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

Выполняет поиск указанного значения и возвращает индекс его первого вхождения. Значения сравниваются с помощью IEquatable {T}.Equals (T).

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

Выполняет поиск указанной последовательности и возвращает индекс ее первого вхождения. Значения сравниваются с помощью IEquatable {T}.Equals (T).

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

Выполняет поиск первого индекса любого из указанных значений аналогичного вызову IndexOf несколько раз с помощью логического оператора ИЛИ.

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

Выполняет поиск первого индекса любого из указанных значений аналогичного вызову IndexOf несколько раз с помощью логического оператора ИЛИ.

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

Выполняет поиск первого индекса любого из указанных значений аналогичного вызову IndexOf несколько раз с помощью логического оператора ИЛИ.

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

Выполняет поиск указанного значения и возвращает индекс его последнего вхождения. Значения сравниваются с помощью IEquatable {T}.Equals (T).

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

Выполняет поиск указанной последовательности и возвращает индекс ее последнего вхождения. Значения сравниваются с помощью IEquatable {T}.Equals (T).

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

Выполняет поиск последнего индекса любого из указанных значений аналогичного вызову LastIndexOf несколько раз с помощью логического оператора ИЛИ.

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

Выполняет поиск последнего индекса любого из указанных значений аналогичного вызову LastIndexOf несколько раз с помощью логического оператора ИЛИ.

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

Выполняет поиск последнего индекса любого из указанных значений аналогичного вызову LastIndexOf несколько раз с помощью логического оператора ИЛИ.

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

Определяет, перекрываются ли диапазон и диапазон только для чтения в памяти.

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

Определяет, перекрываются ли диапазон и диапазон только для чтения в памяти, и выводит смещение элементов.

Reverse<T>(Span<T>)

Изменяет порядок элементов во всем массиве на обратный.

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

Определяет относительный порядок диапазона и диапазона только для чтения путем сравнения их элементов с помощью IComparable{T}.CompareTo (T).

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

Определяет, равны ли диапазон и диапазон только для чтения, сравнивая элементы с помощью IEquatable{T}.Equals (T).

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

Определяет, равны ли две последовательности, сравнивая элементы с помощью IEqualityComparer<T> .

Sort<T>(Span<T>)

Сортирует элементы во всем, Span<T> используя IComparable<T> реализацию каждого элемента Span<T> .

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

Сортирует элементы во всем списке Span<T> с использованием указанного Comparison<T>.

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

Сортирует элементы во всем Span<T> с использованием TComparer.

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

Сортирует пару диапазонов (один диапазон с ключами, а второй с соответствующими элементами) на основе ключей в первом Span<T> с использованием реализации IComparable<T> каждого ключа.

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

Сортирует пару диапазонов (один диапазон с ключами, а второй с соответствующими элементами) на основе ключей в первом Span<T> с использованием указанного сравнения.

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

Сортирует пару диапазонов (один диапазон с ключами, а второй с соответствующими элементами) на основе ключей в первом Span<T> с использованием указанного компаратора.

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

Определяет, отображается ли указанная последовательность в начале диапазона.

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

Удаляет все начальные и конечные вхождения указанного элемента из диапазона.

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

Удаляет все начальные и конечные вхождения набора элементов, указанного в диапазоне только для чтения, из диапазона.

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

Удаляет все конечные вхождения указанного элемента из диапазона.

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

Удаляет все конечные вхождения набора элементов, указанного в диапазоне только для чтения, из диапазона.

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

Удаляет все начальные вхождения указанного элемента из диапазона.

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

Удаляет все начальные вхождения набора элементов, указанного в диапазоне только для чтения, из диапазона.

Применяется к

См. также раздел