Tipos de estrutura ref
(referência de C#)
Você pode usar o modificador ref
na declaração de um tipo de estrutura. As instâncias de um tipo ref struct
são alocadas na pilha e não podem escapar para o heap gerenciado. Para garantir isso, o compilador limita o uso de tipos ref struct
da seguinte maneira:
- Um
ref struct
não pode ser o tipo de elemento de uma matriz. - Um
ref struct
não pode ser um tipo declarado de um campo de uma classe ou um nãoref struct
. - Um
ref struct
não pode implementar interfaces. - Um
ref struct
não pode ser demarcado para System.ValueType ou System.Object. - Um
ref struct
não pode ser um argumento de tipo. - Uma variável
ref struct
não pode ser capturada por uma expressão lambda ou uma função local. - Uma variável
ref struct
não pode ser usada em um métodoasync
. No entanto, você pode usar variáveisref struct
em métodos síncronos, por exemplo, em métodos que retornam Task ou Task<TResult>. - Uma variável
ref struct
não pode ser usada em iteradores.
Você pode definir um ref struct
descartável. Para fazer isso, verifique se um ref struct
se encaixa no padrão descartável. Ou seja, ele tem um método de instância Dispose
, que é acessível, sem parâmetros e tem um tipo void
de retorno. Você pode usar a instrução ou declaração using com uma instância de um ref struct
descartável.
Normalmente, você define um tipo de ref struct
quando precisa de um tipo que também inclua membros de dados de tipos de ref struct
:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
Para declarar um ref struct
como readonly
, combine os modificadores readonly
e ref
na declaração de tipo (o modificador readonly
deve vir antes do 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; }
}
No .NET, exemplos de um ref struct
são System.Span<T> e System.ReadOnlySpan<T>.
Campos ref
A partir do C# 11, você pode declarar um campo ref
em um ref struct
, como mostra o exemplo a seguir:
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;
}
}
Um campo ref
pode ter o valor null
. Use o método Unsafe.IsNullRef<T>(T) para determinar se um campo ref
é null
.
Você pode aplicar o modificador readonly
a um campo ref
das seguintes maneiras:
readonly ref
: você pode fazer reatribuição de ref desse campo com o operador= ref
somente dentro de um construtor ou uminit
acessador. Você pode atribuir um valor com o operador=
a qualquer momento permitido pelo modificador de acesso ao campo.ref readonly
: você nunca poderá atribuir um valor com o operador=
a esse campo. No entanto, você pode fazer reatribuição de ref de um campo com o operador= ref
.readonly ref readonly
: você só pode fazer reatribuição de ref desse campo em um construtor ou acessadorinit
. Em nenhum momento, você não pode atribuir um valor ao campo.
O compilador garante que uma referência armazenada no campo ref
não sobreviva ao valor ao qual se refere.
O recurso de campos ref
permite uma implementação 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...
}
O tipo Span<T>
armazena uma referência por meio da qual acessa os elementos contíguos na memória. O uso de uma referência permite que uma instância Span<T>
evite copiar o armazenamento ao qual se refere.
Especificação da linguagem C#
Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:
Para obter mais informações sobre os campos ref
, confira a nota de proposta Aprimoramentos de struct de baixo nível.
Confira também
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de