instrução fixa (referência de C#)

A fixed instrução impede que o coletor de lixo realoque uma variável movevel e declara um ponteiro para essa variável:

unsafe
{
    byte[] bytes = { 1, 2, 3 };
    fixed (byte* pointerToFirst = bytes)
    {
        Console.WriteLine($"The address of the first array element: {(long)pointerToFirst:X}.");
        Console.WriteLine($"The value of the first array element: {*pointerToFirst}.");
    }
}
// Output is similar to:
// The address of the first array element: 2173F80B5C8.
// The value of the first array element: 1.

O endereço de uma variável fixa ou fixada não é alterado durante a instrução. Você pode usar o ponteiro declarado somente dentro da instrução correspondente fixed . O ponteiro declarado é readonly e não pode ser modificado.

Observação

Você pode usar a fixed instrução somente em um contexto não seguro . O código que contém blocos não seguros deve ser compilado com a opção do compilador AllowUnsafeBlocks.

Você pode inicializar o ponteiro declarado da seguinte maneira:

  • Com uma matriz, como mostra o exemplo no início deste artigo. O ponteiro inicializado contém o endereço do primeiro elemento de matriz.

  • Com um endereço de uma variável. Use o endereço do & operador, como mostra o seguinte exemplo:

    unsafe
    {
        int[] numbers = { 10, 20, 30 };
        fixed (int* toFirst = &numbers[0], toLast = &numbers[^1])
        {
            Console.WriteLine(toLast - toFirst);  // output: 2
        }
    }
    

    Os campos de objeto são outro exemplo de variáveis moveveis que podem ser fixadas.

    Quando o ponteiro inicializado contém o endereço de um campo de objeto ou de um elemento de matriz, a fixed instrução garante que o coletor de lixo não seja realocado ou descarte da instância de objeto que contém durante a execução do corpo da instrução.

  • Com a instância do tipo que implementa um método chamado GetPinnableReference. Esse método deve retornar uma ref variável de um tipo não gerenciado. Os tipos System.Span<T> .NET e System.ReadOnlySpan<T> fazer uso desse padrão. Você pode fixar instâncias de span, como mostra o exemplo a seguir:

    unsafe
    {
        int[] numbers = { 10, 20, 30, 40, 50 };
        Span<int> interior = numbers.AsSpan()[1..^1];
        fixed (int* p = interior)
        {
            for (int i = 0; i < interior.Length; i++)
            {
                Console.Write(p[i]);  
            }
            // output: 203040
        }
    }
    

    Para obter mais informações, veja a referência de API Span<T>.GetPinnableReference().

  • Com uma cadeia de caracteres, como mostra o exemplo a seguir:

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • Com um buffer de tamanho fixo.

Você pode alocar memória na pilha, onde ela não está sujeita à coleta de lixo e, portanto, não precisa ser fixada. Para fazer isso, use uma expressão stackalloc.

Você também pode usar a fixedpalavra-chave para declarar um buffer de tamanho fixo.

Especificação da linguagem C#

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

Para obter informações sobre a instrução baseada em fixed padrão, consulte a nota de proposta de recurso de instrução baseada em fixed padrão .

Confira também