Span<T> Структура
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет типобезопасное и безопасное в памяти представление непрерывной области произвольной памяти.
generic <typename T>
public value class Span
public readonly ref struct Span<T>
[System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))]
public readonly ref struct Span<T>
type Span<'T> = struct
[<System.Runtime.InteropServices.Marshalling.NativeMarshalling(typeof(System.Runtime.InteropServices.Marshalling.SpanMarshaller<,>))>]
type Span<'T> = struct
Public Structure Span(Of T)
Параметры типа
- T
Тип элементов в Span<T>.
- Наследование
- Атрибуты
Комментарии
Span<T>
— это структура ссылки , которая выделяется в стеке, а не в управляемой куче. Типы ссылочных структур имеют ряд ограничений, чтобы гарантировать, что они не могут быть повышены до управляемой кучи, в том числе их нельзя упаковать, они не могут быть назначены переменным типа Objectdynamic
или любому типу интерфейса, они не могут быть полями в ссылочных типах и не могут использоваться через await
границы и yield
. Кроме того, вызовы двух методов, Equals(Object) и GetHashCode, вызывают исключение NotSupportedException.
Важно!
Так как это тип только для стека, Span<T>
он не подходит для многих сценариев, требующих хранения ссылок на буферы в куче. Это относится, например, к подпрограммам, которые выполняют асинхронные вызовы методов. Для таких сценариев можно использовать дополнительные System.Memory<T> типы и System.ReadOnlyMemory<T> .
Для диапазонов, представляющих неизменяемые структуры или структуры только для чтения, используйте System.ReadOnlySpan<T>.
Span<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
В следующем примере создается 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
// 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
В следующем примере используется ключевое слово stackalloc C# для выделения 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> и массивы
При создании оболочки для массива Span<T>
может быть весь массив, как это было в примерах в разделе Span<T> и память . Так как он поддерживает срезы, Span<T>
может также указывать на любой смежный диапазон в массиве.
В следующем примере создается срез из пяти средних элементов 10-элементного целочисленного массива. Обратите внимание, что код удваивает значения каждого целого числа в срезе. Как видно из выходных данных, изменения, внесенные диапазоном, отражаются в значениях массива.
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> и срезы
Span<T>
включает две перегрузки Slice метода , образующие срез текущего диапазона, который начинается с указанного индекса. Это позволяет рассматривать данные в Span<T>
как набор логических блоков, которые могут обрабатываться по мере необходимости частями конвейера обработки данных с минимальным влиянием на производительность. Например, так как современные серверные протоколы часто основаны на тексте, особенно важно манипулировать строками и подстроками. String В классе основным методом для извлечения подстрок является Substring. Для конвейеров данных, которые используют обширные операции со строками, их использование обеспечивает некоторые ограничения производительности, так как:
Создает новую строку для хранения подстроки.
Копирует подмножество символов из исходной строки в новую строку.
Эту операцию выделения и копирования можно устранить с помощью 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) |
Создает новый Span<T> объект длиной 1 вокруг указанной ссылки. |
Span<T>(T[]) |
Создает новый объект Span<T> по всему указанному массиву. |
Span<T>(T[], Int32, Int32) |
Создает новый объект Span<T>, который включает указанное число элементов массива, начиная с указанного индекса. |
Span<T>(Void*, Int32) |
Создает новый Span<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> неравными. |
Методы расширения
ToImmutableArray<T>(Span<T>) |
Преобразует диапазон в неизменяемый массив. |
BinarySearch<T>(Span<T>, IComparable<T>) |
Выполняет поиск значения во всем отсортированном массиве Span<T>, используя заданный универсальный интерфейс IComparable<T>. |
BinarySearch<T,TComparer>(Span<T>, T, TComparer) |
Выполняет поиск указанного значения во всем отсортированном массиве Span<T>, используя заданный универсальный тип |
BinarySearch<T,TComparable>(Span<T>, TComparable) |
Выполняет поиск значения во всем отсортированном массиве Span<T>, используя заданный универсальный тип |
CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>) |
Находит длину любого общего префикса, совместно используемого между |
CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
Находит длину любого общего префикса, совместно используемого между |
Contains<T>(Span<T>, T) |
Указывает, найдено ли указанное значение в диапазоне. Значения сравниваются с помощью IEquatable {T}.Equals (T). |
ContainsAny<T>(Span<T>, T, T) |
Выполняет поиск экземпляра |
ContainsAny<T>(Span<T>, T, T, T) |
Выполняет поиск экземпляра |
ContainsAny<T>(Span<T>, SearchValues<T>) |
Выполняет поиск экземпляра любого из указанных |
ContainsAny<T>(Span<T>, ReadOnlySpan<T>) |
Выполняет поиск экземпляра любого из указанных |
ContainsAnyExcept<T>(Span<T>, T) |
Ищет любое значение, отличное от указанного |
ContainsAnyExcept<T>(Span<T>, T, T) |
Ищет любое значение, отличное от |
ContainsAnyExcept<T>(Span<T>, T, T, T) |
Ищет любое значение, отличное от |
ContainsAnyExcept<T>(Span<T>, SearchValues<T>) |
Ищет любое значение, отличное от указанного |
ContainsAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Ищет любое значение, отличное от указанного |
ContainsAnyExceptInRange<T>(Span<T>, T, T) |
Выполняет поиск любого значения за пределами диапазона между |
ContainsAnyInRange<T>(Span<T>, T, T) |
Выполняет поиск любого значения в диапазоне между |
Count<T>(Span<T>, T) |
Подсчитывает количество указанных событий |
Count<T>(Span<T>, ReadOnlySpan<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>, SearchValues<T>) |
Выполняет поиск первого индекса любого из указанных значений. |
IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Выполняет поиск первого индекса любого из указанных значений аналогичного вызову IndexOf несколько раз с помощью логического оператора ИЛИ. |
IndexOfAnyExcept<T>(Span<T>, T) |
Ищет первый индекс любого значения, отличного от указанного |
IndexOfAnyExcept<T>(Span<T>, T, T) |
Выполняет поиск первого индекса любого значения, отличного от указанного |
IndexOfAnyExcept<T>(Span<T>, T, T, T) |
Выполняет поиск первого индекса любого значения, отличного от указанного |
IndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Ищет первый индекс любого значения, отличного от указанного |
IndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Ищет первый индекс любого значения, отличного от указанного |
IndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Выполняет поиск первого индекса любого значения за пределами диапазона между |
IndexOfAnyInRange<T>(Span<T>, T, T) |
Выполняет поиск первого индекса любого значения в диапазоне между |
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>, SearchValues<T>) |
Выполняет поиск последнего индекса любого из указанных значений. |
LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Выполняет поиск последнего индекса любого из указанных значений аналогичного вызову LastIndexOf несколько раз с помощью логического оператора ИЛИ. |
LastIndexOfAnyExcept<T>(Span<T>, T) |
Выполняет поиск последнего индекса любого значения, отличного от указанного |
LastIndexOfAnyExcept<T>(Span<T>, T, T) |
Выполняет поиск последнего индекса любого значения, отличного от указанного |
LastIndexOfAnyExcept<T>(Span<T>, T, T, T) |
Выполняет поиск последнего индекса любого значения, кроме указанного |
LastIndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Выполняет поиск последнего индекса любого значения, отличного от указанного |
LastIndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Выполняет поиск последнего индекса любого значения, отличного от указанного |
LastIndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Выполняет поиск последнего индекса любого значения за пределами диапазона между |
LastIndexOfAnyInRange<T>(Span<T>, T, T) |
Выполняет поиск последнего индекса любого значения в диапазоне между |
Overlaps<T>(Span<T>, ReadOnlySpan<T>) |
Определяет, перекрываются ли диапазон и диапазон только для чтения в памяти. |
Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) |
Определяет, перекрываются ли диапазон и диапазон только для чтения в памяти, и выводит смещение элементов. |
Replace<T>(Span<T>, T, T) |
Заменяет все вхождения |
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> с использованием |
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>) |
Удаляет все начальные вхождения набора элементов, указанного в диапазоне только для чтения, из диапазона. |
Применяется к
См. также раздел
Обратная связь
Отправить и просмотреть отзыв по