ref tipos de estrutura (referência C#)

Você pode usar o ref modificador na declaração de um tipo de estrutura. As instâncias de um ref struct tipo são alocadas na pilha e não podem escapar para o heap gerenciado. Para garantir isso, o compilador limita o uso de ref struct tipos da seguinte maneira:

  • A ref struct não pode ser o tipo de elemento de uma matriz.
  • A ref struct não pode ser um tipo declarado de um campo de uma classe ou um não-ref struct.
  • A ref struct não pode implementar interfaces.
  • A ref struct não pode ser encaixotado para System.ValueType ou System.Object.
  • A ref struct não pode ser um argumento de tipo.
  • Uma ref struct variável não pode ser capturada por uma expressão lambda ou uma função local.
  • Uma ref struct variável não pode ser usada em um async método. No entanto, você pode usar ref struct variáveis em métodos síncronos, por exemplo, em métodos que retornam Task ou Task<TResult>.
  • Uma ref struct variável não pode ser usada em iteradores.

Você pode definir um descartável ref struct. Para fazer isso, certifique-se de que 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 de void retorno. Você pode usar a instrução using ou declaração com uma instância de um descartável ref struct.

Normalmente, você define um ref struct tipo quando precisa de um tipo que também inclui membros de dados de ref struct tipos:

public ref struct CustomRef
{
    public bool IsValid;
    public Span<int> Inputs;
    public Span<int> Outputs;
}

Para declarar a ref struct como readonly, combine os readonly modificadores e ref na declaração de tipo (o readonly modificador deve vir antes do ref modificador):

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>.

ref campos

A partir do C# 11, você pode declarar um ref campo 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 ref campo pode ter o null valor. Use o Unsafe.IsNullRef<T>(T) método para determinar se um ref campo é null.

Você pode aplicar o readonly modificador a um ref campo das seguintes maneiras:

  • readonly ref: Você pode ref reatribuir tal campo com o operador apenas dentro de = ref um construtor ou um init acessador. Você pode atribuir um valor com o = operador em qualquer ponto permitido pelo modificador de acesso ao campo.
  • ref readonly: Em qualquer momento, você não pode atribuir um valor com o = operador a esse campo. No entanto, você pode ref reatribuir um campo com o = ref operador.
  • readonly ref readonly: Você só pode ref reatribuir tal campo em um construtor ou acessador init . A qualquer momento, não é possível atribuir um valor ao campo.

O compilador garante que uma referência armazenada em um ref campo não sobreviva ao seu referente.

O ref recurso de campos 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 Span<T> tipo armazena uma referência através da qual ele acessa os elementos contíguos na memória. O uso de uma referência permite que uma Span<T> instância evite copiar o armazenamento ao qual se refere.

Especificação da linguagem C#

Para obter mais informações, consulte as seguintes seções da especificação da linguagem C#:

Para obter mais informações sobre ref campos, consulte a nota da proposta de melhorias de estrutura de baixo nível.

Consulte também