Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Tipos de estructura
Use el ref modificador al declarar un tipo de estructura. Asigna instancias de un ref struct tipo en la pila y no pueden escapar al montón administrado. Para garantizar esta propiedad, el compilador limita el uso de ref struct tipos de la siguiente manera:
- No se puede usar
ref structcomo el tipo de elemento de una matriz. - No se puede declarar
ref structcomo el tipo de un campo en una clase o un noref struct. - No se puede boxear en
ref structSystem.ValueType o System.Object. - No se puede capturar una
ref structvariable en una expresión lambda ni en una función local. - Antes de C# 13, no puede usar
ref structvariables en unasyncmétodo . A partir de C# 13, no se puede usar una variableref structen el mismo bloque que la expresiónawaiten un métodoasync. Sin embargo, puede usar variables deref structen métodos sincrónicos, como los que devuelven Task o Task<TResult>. - Antes de C# 13, no se puede usar una
ref structvariable en iteradores. A partir de C# 13, se pueden usar tiposref structy localesrefen iteradores, siempre que no estén en segmentos de código con la instrucciónyield return. - Antes de C# 13, un
ref structno puede implementar interfaces. A partir de C# 13, una estructurarefpuede implementar interfaces, pero debe cumplir las reglas de seguridad de ref. Por ejemplo, un tiporef structno se puede convertir al tipo de interfaz porque requiere una conversión boxing. - Antes de C# 13, un
ref structno puede ser un argumento de tipo. A partir de C# 13, unref structpuede ser el argumento type cuando el parámetro type especifica elallows ref structen su cláusulawhere.
La referencia del lenguaje C# documenta la versión publicada más recientemente del lenguaje C#. También contiene documentación inicial sobre las características de las versiones preliminares públicas de la próxima versión del lenguaje.
La documentación identifica cualquier característica introducida por primera vez en las últimas tres versiones del idioma o en las versiones preliminares públicas actuales.
Sugerencia
Para buscar cuándo se introdujo por primera vez una característica en C#, consulte el artículo sobre el historial de versiones del lenguaje C#.
Normalmente, se define un tipo ref struct cuando se necesita un tipo que también incluya miembros de datos de tipos ref struct:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
Para declarar ref struct como readonly, combine los modificadores readonly y ref en la declaración de tipos (el modificador readonly debe ir delante del modificador ref):
public readonly ref struct ConversionRequest
{
public ConversionRequest(double rate, ReadOnlySpan<double> values)
{
Rate = rate;
Values = values;
}
public double Rate { get; }
public ReadOnlySpan<double> Values { get; }
}
En .NET, ref struct y System.Span<T> son ejemplos de una clase System.ReadOnlySpan<T>.
Campos ref
Puede declarar un ref campo en , ref structcomo se muestra en el ejemplo siguiente:
public ref struct RefFieldExample
{
private ref int number;
public int GetNumber()
{
if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
{
throw new InvalidOperationException("The number ref field is not initialized.");
}
return number;
}
}
Un campo ref puede tener el valor null. Use el método Unsafe.IsNullRef<T>(T) para determinar si un campo ref es null.
Puede aplicar el modificador readonly a un campo ref de varias formas:
-
readonly ref: puede reasignar este campo mediante el= refoperador solo dentro de un constructor o uninitdescriptor de acceso. Puede asignar un valor con el operador=en cualquier punto permitido por el modificador de acceso del campo. -
ref readonly: en cualquier momento, no se puede asignar un valor con el=operador a este campo. Sin embargo, puede volver a asignar el campo mediante el= refoperador . -
readonly ref readonly: solo puede reasignar este campo en un constructor o uninitdescriptor de acceso. No puede asignar un valor al campo en ningún momento.
El compilador se asegura de que una referencia almacenada en un campo ref no sobreviva al valor al que hace referencia.
La característica de campos ref permite una implementación segura de tipos como System.Span<T>:
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
El tipo Span<T> almacena una referencia a través de la cual accede a los elementos contiguos en memoria. Mediante el uso de una referencia, una Span<T> instancia evita copiar el almacenamiento al que hace referencia.
El patrón descartable
Puede definir un elemento ref struct descartable. Para ello, asegúrese de que el elemento ref struct se ajuste al patrón descartable. Es decir, tiene un método de instancia Dispose accesible, sin parámetros y tiene un void tipo de valor devuelto. Puede usar la instrucción using o declaración con una instancia de un elemento descartable ref struct.
A partir de C# 13, también puede implementar el IDisposable en tipos ref struct. Sin embargo, la resolución de sobrecarga prefiere el patrón descartable para el método de interfaz. El compilador se resuelve en un IDisposable.Dispose método solo cuando no se encuentra un método adecuado Dispose .
Restricciones para los tipos ref struct que implementan una interfaz
Estas restricciones garantizan que un ref struct tipo que implemente una interfaz siga las reglas de seguridad ref necesarias.
- No se puede convertir en una
ref structinstancia de una interfaz que implementa. Esta restricción incluye la conversión implícita cuando se usa unref structtipo como argumento y el parámetro es un tipo de interfaz. La conversión da como resultado una conversión boxing, que infringe la seguridad ref. Unref structpuede declarar métodos como declaraciones de interfaz explícitas. Sin embargo, solo puede acceder a esos métodos desde métodos genéricos donde los tipos de parámetroallows ref structde tipo. - Un
ref structque implementa una interfaz debe implementar todos los miembros de la interfaz de instancia. Elref structdebe implementar miembros de instancia incluso cuando la interfaz incluye una implementación predeterminada.
El compilador aplica estas restricciones. Si escribe tipos ref struct que implementan interfaces, cada nueva actualización puede incluir nuevos miembros de interfaz predeterminados. Hasta que proporcione una implementación para los nuevos métodos de instancia, la aplicación no se compila. No se puede proporcionar una implementación específica para un método de interfaz static con una implementación predeterminada.
Importante
La implementación de una interfaz con un ref struct tipo presenta la posibilidad de cambios posteriores de interrupción del origen y de interrupción binaria. La interrupción se produce si ref struct implementa una interfaz definida en otro ensamblado y ese ensamblado proporciona una actualización que agrega miembros predeterminados a esa interfaz.
La interrupción de origen se produce cuando se vuelve a compilar ref struct: debe implementar el nuevo miembro, aunque haya una implementación predeterminada.
La interrupción binaria se produce si actualiza el ensamblado externo sin volver a compilar el ref struct tipo y el código actualizado llama a la implementación predeterminada del nuevo método. El tiempo de ejecución produce una excepción cuando se accede al miembro predeterminado.
especificación del lenguaje C#
Para más información, vea las secciones siguientes de la Especificación del lenguaje C#:
Para obtener más información sobre los campos ref, consulte la nota de propuesta de mejoras de estructura de bajo nivel.