Span<T> Estructura
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Proporciona una representación segura para tipos y segura para memoria de una región contigua de memoria arbitraria.
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)
Parámetros de tipo
- T
Tipo de elementos de Span<T>.
- Herencia
- Atributos
Comentarios
El Span<T> tipo es una estructura de referencia que se asigna en la pila en lugar de en el montón administrado. Los tipos de estructura ref tienen algunas restricciones para asegurarse de que no se pueden promover al montón administrado, lo que incluye que no pueden ser:
- Boxed.
- Asignado a variables de tipo Object o
dynamic, o a cualquier tipo de interfaz. - Campos de un tipo de referencia.
- Se usa entre
awaitlímites yyield.
Además, las llamadas a los dos métodos Equals(Object) y GetHashCode lanzan una NotSupportedException excepción.
Importante
Dado que es un tipo que solo se puede utilizar en la pila, Span<T> no es adecuado para muchos escenarios que requieren almacenar referencias a búferes en el montón. Esto es cierto, por ejemplo, de rutinas que realizan llamadas de método asincrónico. En estos escenarios, puede usar los tipos complementarios System.Memory<T> y System.ReadOnlyMemory<T>.
Para los intervalos que representan estructuras inmutables o de solo lectura, use System.ReadOnlySpan<T>.
Memoria
Span<T> representa una región contigua de memoria arbitraria. A menudo se usa una Span<T> instancia para contener los elementos de una matriz o una parte de una matriz. Sin embargo, a diferencia de una matriz, una Span<T> instancia puede apuntar a la memoria administrada, la memoria nativa o la memoria administrada en la pila. En el ejemplo siguiente se crea un Span<Byte> a partir de una matriz.
// 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
En el ejemplo siguiente se crea un Span<Byte> a partir de 100 bytes de memoria nativa.
// 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
En el ejemplo siguiente se usa la palabra clave stackalloc de C# para asignar 100 bytes de memoria en la pila:
// 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
Dado que Span<T> es una abstracción sobre un bloque arbitrario de memoria, los métodos del tipo Span<T> y los métodos que tienen parámetros Span<T> funcionan en cualquier objeto Span<T> independientemente del tipo de memoria que encapsula. Por ejemplo, cada una de las secciones independientes del código que inicializan el intervalo y calculan la suma de sus elementos se pueden refactorizar en métodos de inicialización y cálculo únicos, como se muestra en el ejemplo siguiente:
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
Arreglos
Cuando encapsula una matriz, Span<T> puede encapsular una matriz completa, como hizo en los ejemplos de la sección Memoria . Dado que admite la segmentación, Span<T> también puede apuntar a cualquier intervalo contiguo dentro de la matriz.
En el ejemplo siguiente se crea un segmento de los cinco elementos intermedios de una matriz de enteros de 10 elementos. Tenga en cuenta que el código duplica los valores de cada entero del segmento. Como se muestra en el resultado, los cambios realizados por el rango se reflejan en los valores de la matriz.
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
Fragmentos
Span<T> incluye dos sobrecargas del Slice método que forman un segmento fuera del intervalo actual que comienza en un índice especificado. Esto permite tratar los datos en Span<T> como un conjunto de fragmentos lógicos que pueden ser procesados por secciones de una tubería de procesamiento de datos según sea necesario, con un impacto mínimo en el rendimiento. Por ejemplo, dado que los protocolos de servidor modernos suelen basarse en texto, la manipulación de cadenas y subcadenas es especialmente importante. En la String clase , el método principal para extraer subcadenas es Substring. En el caso de las canalizaciones de datos que dependen de una manipulación extensa de cadenas, su uso ofrece algunas penalizaciones de rendimiento, ya que:
- Crea una nueva cadena para contener la subcadena.
- Copia un subconjunto de los caracteres de la cadena original a la nueva cadena.
Esta operación de asignación y copia se puede eliminar mediante Span<T> o ReadOnlySpan<T>, como se muestra en el ejemplo siguiente:
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
Constructores
| Nombre | Description |
|---|---|
| Span<T>(T) |
Crea una nueva Span<T> longitud 1 alrededor de la referencia especificada. |
| Span<T>(T[], Int32, Int32) |
Crea un nuevo Span<T> objeto que incluye un número especificado de elementos de una matriz a partir de un índice especificado. |
| Span<T>(T[]) |
Crea un nuevo Span<T> objeto sobre la totalidad de una matriz especificada. |
| Span<T>(Void*, Int32) |
Crea un nuevo Span<T> objeto a partir de un número especificado de elementos a partir de |
Propiedades
| Nombre | Description |
|---|---|
| Empty |
Devuelve un objeto vacío Span<T> . |
| IsEmpty |
Devuelve un valor que indica si el objeto actual Span<T> está vacío. |
| Item[Int32] |
Obtiene el elemento en el índice de base cero especificado. |
| Length |
Devuelve la longitud del intervalo actual. |
Métodos
| Nombre | Description |
|---|---|
| Clear() |
Borra el contenido de este Span<T> objeto. |
| CopyTo(Span<T>) | |
| Equals(Object) |
Obsoletos.
Obsoletos.
No se admiten llamadas a este método. |
| Fill(T) |
Rellena los elementos de este intervalo con un valor especificado. |
| GetEnumerator() |
Devuelve un enumerador para este Span<T>objeto . |
| GetHashCode() |
Obsoletos.
Genera una NotSupportedException. |
| GetPinnableReference() |
Devuelve una referencia a un objeto de tipo T que se puede usar para anclar. Este método está diseñado para admitir compiladores de .NET y no está diseñado para que el código de usuario lo llame. |
| Slice(Int32, Int32) |
Forma un segmento fuera del intervalo actual a partir de un índice especificado para una longitud especificada. |
| Slice(Int32) |
Forma un segmento del intervalo actual que comienza en un índice especificado. |
| ToArray() |
Copia el contenido de este intervalo en una nueva matriz. |
| ToString() |
Devuelve la representación de cadena de este Span<T> objeto. |
| TryCopyTo(Span<T>) |
Intenta copiar el actual Span<T> en un destino Span<T> y devuelve un valor que indica si la operación de copia se realizó correctamente. |
Operadores
| Nombre | Description |
|---|---|
| Equality(Span<T>, Span<T>) |
Devuelve un valor que indica si dos Span<T> objetos son iguales. |
| Implicit(ArraySegment<T> to Span<T>) |
Define una conversión implícita de a ArraySegment<T> .Span<T> |
| Implicit(Span<T> to ReadOnlySpan<T>) |
Define una conversión implícita de a Span<T> .ReadOnlySpan<T> |
| Implicit(T[] to Span<T>) |
Define una conversión implícita de una matriz en .Span<T> |
| Inequality(Span<T>, Span<T>) |
Devuelve un valor que indica si dos Span<T> objetos no son iguales. |
Métodos de extensión
| Nombre | Description |
|---|---|
| BinarySearch<T,TComparable>(Span<T>, TComparable) |
Busca en un valor completo Span<T> un valor mediante el tipo genérico especificado |
| BinarySearch<T,TComparer>(Span<T>, T, TComparer) |
Busca en un valor especificado un valor Span<T> completo ordenado mediante el tipo genérico especificado |
| BinarySearch<T>(Span<T>, IComparable<T>) |
Busca en un valor completo Span<T> un valor mediante la interfaz genérica especificada IComparable<T> . |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
Busca la longitud de cualquier prefijo común compartido entre |
| CommonPrefixLength<T>(Span<T>, ReadOnlySpan<T>) |
Busca la longitud de cualquier prefijo común compartido entre |
| Contains<T>(Span<T>, T) |
Indica si se encuentra un valor especificado en un intervalo. |
| ContainsAny<T>(Span<T>, ReadOnlySpan<T>) |
Busca una aparición de cualquiera de los valores especificados |
| ContainsAny<T>(Span<T>, SearchValues<T>) |
Busca una aparición de cualquiera de los valores especificados |
| ContainsAny<T>(Span<T>, T, T, T) |
Busca una aparición de |
| ContainsAny<T>(Span<T>, T, T) |
Busca una aparición de |
| ContainsAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Busca en el intervalo especificado cualquier valor distinto del especificado |
| ContainsAnyExcept<T>(Span<T>, SearchValues<T>) |
Busca en el intervalo especificado cualquier valor distinto del especificado |
| ContainsAnyExcept<T>(Span<T>, T, T, T) |
Busca cualquier valor distinto de |
| ContainsAnyExcept<T>(Span<T>, T, T) |
Busca en el intervalo especificado cualquier valor distinto de |
| ContainsAnyExcept<T>(Span<T>, T) |
Busca en el intervalo especificado cualquier valor distinto del especificado |
| ContainsAnyExceptInRange<T>(Span<T>, T, T) |
Busca cualquier valor fuera del intervalo entre |
| ContainsAnyInRange<T>(Span<T>, T, T) |
Busca cualquier valor en el intervalo entre |
| Count<T>(Span<T>, ReadOnlySpan<T>) |
Cuenta el número de veces que se produce el especificado |
| Count<T>(Span<T>, T) |
Cuenta el número de veces que se produce el especificado |
| EndsWith<T>(Span<T>, ReadOnlySpan<T>) |
Determina si la secuencia especificada aparece al final de un intervalo. |
| IndexOf<T>(Span<T>, ReadOnlySpan<T>) |
Busca la secuencia especificada y devuelve el índice de su primera aparición. |
| IndexOf<T>(Span<T>, T) |
Busca el valor especificado y devuelve el índice de su primera aparición. |
| IndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Busca el primer índice de cualquiera de los valores especificados. |
| IndexOfAny<T>(Span<T>, SearchValues<T>) |
Busca el primer índice de cualquiera de los valores especificados. |
| IndexOfAny<T>(Span<T>, T, T, T) |
Busca el primer índice de cualquiera de los valores especificados. |
| IndexOfAny<T>(Span<T>, T, T) |
Busca el primer índice de cualquiera de los valores especificados. |
| IndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Busca el primer índice de cualquier valor distinto del especificado |
| IndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Busca el primer índice de cualquier valor distinto del especificado |
| IndexOfAnyExcept<T>(Span<T>, T, T, T) |
Busca el primer índice de cualquier valor distinto de |
| IndexOfAnyExcept<T>(Span<T>, T, T) |
Busca el primer índice de cualquier valor distinto de los dos valores especificados. |
| IndexOfAnyExcept<T>(Span<T>, T) |
Busca el primer índice de cualquier valor distinto del especificado |
| IndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Busca el primer índice de cualquier valor fuera del intervalo entre |
| IndexOfAnyInRange<T>(Span<T>, T, T) |
Busca el primer índice de cualquier valor del intervalo entre |
| LastIndexOf<T>(Span<T>, ReadOnlySpan<T>) |
Busca la secuencia especificada y devuelve el índice de su última aparición. |
| LastIndexOf<T>(Span<T>, T) |
Busca el valor especificado y devuelve el índice de su última aparición. |
| LastIndexOfAny<T>(Span<T>, ReadOnlySpan<T>) |
Busca el último índice de cualquiera de los valores especificados. |
| LastIndexOfAny<T>(Span<T>, SearchValues<T>) |
Busca el último índice de cualquiera de los valores especificados. |
| LastIndexOfAny<T>(Span<T>, T, T, T) |
Busca el último índice de cualquiera de los valores especificados. |
| LastIndexOfAny<T>(Span<T>, T, T) |
Busca el último índice de cualquiera de los valores especificados. |
| LastIndexOfAnyExcept<T>(Span<T>, ReadOnlySpan<T>) |
Busca el último índice de cualquier valor distinto del especificado |
| LastIndexOfAnyExcept<T>(Span<T>, SearchValues<T>) |
Busca el último índice de cualquier valor distinto del especificado |
| LastIndexOfAnyExcept<T>(Span<T>, T, T, T) |
Busca el último índice de cualquier valor distinto del especificado |
| LastIndexOfAnyExcept<T>(Span<T>, T, T) |
Busca el último índice de cualquier valor distinto del especificado |
| LastIndexOfAnyExcept<T>(Span<T>, T) |
Busca el último índice de cualquier valor distinto del especificado |
| LastIndexOfAnyExceptInRange<T>(Span<T>, T, T) |
Busca el último índice de cualquier valor fuera del intervalo entre |
| LastIndexOfAnyInRange<T>(Span<T>, T, T) |
Busca el último índice de cualquier valor del intervalo entre |
| Overlaps<T>(Span<T>, ReadOnlySpan<T>, Int32) |
Determina si un intervalo y un intervalo de solo lectura se superponen en memoria y genera el desplazamiento del elemento. |
| Overlaps<T>(Span<T>, ReadOnlySpan<T>) |
Determina si un intervalo y un intervalo de solo lectura se superponen en la memoria. |
| Replace<T>(Span<T>, T, T, IEqualityComparer<T>) |
Reemplaza todas las repeticiones de |
| Replace<T>(Span<T>, T, T) |
Reemplaza todas las repeticiones de |
| ReplaceAny<T>(Span<T>, SearchValues<T>, T) |
Reemplaza en |
| ReplaceAnyExcept<T>(Span<T>, SearchValues<T>, T) |
Reemplaza en |
| Reverse<T>(Span<T>) |
Invierte la secuencia de los elementos en todo el intervalo. |
| SequenceCompareTo<T>(Span<T>, ReadOnlySpan<T>) |
Determina el orden relativo de un intervalo y un intervalo de solo lectura comparando los elementos mediante IComparable{T}. CompareTo(T). |
| SequenceEqual<T>(Span<T>, ReadOnlySpan<T>, IEqualityComparer<T>) |
Determina si dos secuencias son iguales comparando los elementos mediante .IEqualityComparer<T> |
| SequenceEqual<T>(Span<T>, ReadOnlySpan<T>) |
Determina si un intervalo y un intervalo de solo lectura son iguales comparando los elementos mediante IEquatable{T}. Equals(T). |
| Sort<T,TComparer>(Span<T>, TComparer) |
Ordena los elementos de todo Span<T> mediante . |
| Sort<T>(Span<T>, Comparison<T>) |
Ordena los elementos de todo Span<T> mediante el especificado Comparison<T>. |
| Sort<T>(Span<T>) |
Ordena los elementos de todo Span<T> mediante la IComparable<T> implementación de cada elemento de Span<T>. |
| Sort<TKey,TValue,TComparer>(Span<TKey>, Span<TValue>, TComparer) |
Ordena un par de intervalos (uno que contiene las claves y el otro que contiene los elementos correspondientes) en función de las claves del primero Span<T> mediante el comparador especificado. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>, Comparison<TKey>) |
Ordena un par de intervalos (uno que contiene las claves y el otro que contiene los elementos correspondientes) en función de las claves del primero Span<T> mediante la comparación especificada. |
| Sort<TKey,TValue>(Span<TKey>, Span<TValue>) |
Ordena un par de intervalos (uno que contiene las claves y el otro que contiene los elementos correspondientes) en función de las claves del primero Span<T> mediante la IComparable<T> implementación de cada clave. |
| StartsWith<T>(Span<T>, ReadOnlySpan<T>) |
Determina si una secuencia especificada aparece al principio de un intervalo. |
| ToImmutableArray<T>(Span<T>) |
Convierte el intervalo en una matriz inmutable. |
| Trim<T>(Span<T>, ReadOnlySpan<T>) |
Quita todas las apariciones iniciales y finales de un conjunto de elementos especificados en un intervalo de solo lectura de un intervalo. |
| Trim<T>(Span<T>, T) |
Quita todas las apariciones iniciales y finales de un elemento especificado de un intervalo. |
| TrimEnd<T>(Span<T>, ReadOnlySpan<T>) |
Quita todas las apariciones finales de un conjunto de elementos especificados en un intervalo de solo lectura de un intervalo. |
| TrimEnd<T>(Span<T>, T) |
Quita todas las apariciones finales de un elemento especificado de un intervalo. |
| TrimStart<T>(Span<T>, ReadOnlySpan<T>) |
Quita todas las apariciones iniciales de un conjunto de elementos especificados en un intervalo de solo lectura del intervalo. |
| TrimStart<T>(Span<T>, T) |
Quita todas las apariciones iniciales de un elemento especificado del intervalo. |