Partilhar via


Erro do compilador CS8170

Os membros Struct não podem retornar 'este' ou outros membros da instância por referência

Exemplo

O exemplo a seguir gera CS8170:

Os tipos de valor (ou seja, structs) são geralmente alocados na pilha. Um tipo de valor alocado na pilha torna-se inválido ao sair do escopo onde foi declarado. O compilador evita uma referência a uma variável que se torna inválida deixando o escopo gerando esse erro.

// CS8170.cs (8,14)

struct Program
{
    public int d;

    public ref int M()
    {
        return ref d;
    }
}

public class Other
{
    public void Method()
    {
        var p = new Program();
        ref int d = ref p.M();
    }
}

Para corrigir este erro

Alterar o método para not ref-return corrige este erro:

delegate void D();

struct Program
{
    public event D d;

    public D M()
    {
        return d;
    }
}

Se for necessária uma referência a um membro, considere estender o escopo do valor. Por exemplo:

public struct Program
{
    public int d;
}

public static class Extensions
{
    public static ref readonly int RefD(this in Program program)
    {
        return ref program.d;
    }
}

public class Other
{
    public void Method()
    {
        var p = new Program();
        var d = p.RefD();
    }
}

Outra abordagem é usar o System.Diagnostics.CodeAnalysis.UnscopedRefAttribute atributo. Marcará a referência para poder escapar ao âmbito de aplicação.
Utilize isto apenas quando souber que é seguro para a referência sair do âmbito. Abaixo está o exemplo de aplicação System.Diagnostics.CodeAnalysis.UnscopedRefAttribute ao int M() método, que corrige o CS8170:

using System.Diagnostics.CodeAnalysis;

struct Program
{
    public int d;

    [UnscopedRef]
    public ref int M()
    {
        return ref d;    // No error - ref is valid to escape the scope in this line of that method
    }
}

public class Other
{
    public void Method()
    {
        var p = new Program();
        ref int d = ref p.M();
    }
}