CS8170 fordítóhiba

A strukturált tagok nem adhatják vissza az "ez" vagy más példánytagokat hivatkozás alapján

példa

A következő minta a CS8170-et hozza létre:

Az értéktípusok (azaz struct típusok) leggyakrabban a veremen vannak lefoglalva. A veremen lefoglalt értéktípus érvénytelenné válik, így a hatókör, amelyben deklarálták, érvénytelenné válik. A fordító egy hibát generál azzal, hogy elkerüli azon változó hivatkozását, amely érvénytelenné válik, amikor kilép a hatókörből.

// 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();
    }
}

A hiba kijavítása

Ha a metódust nem ref-return értékre módosítja, a következő hibát javítja ki:

delegate void D();

struct Program
{
    public event D d;

    public D M()
    {
        return d;
    }
}

Ha egy tagra való hivatkozásra van szükség, fontolja meg az érték hatókörének kiterjesztését. Például:

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();
    }
}

Egy másik megközelítés az attribútum használata System.Diagnostics.CodeAnalysis.UnscopedRefAttribute . Meg fogja jelölni azt a hivatkozást, amely lehetővé teszi a hatókör elhagyását.
Ezt csak akkor használja, ha tudja, hogy a hivatkozás biztonságosan elhagyja a hatókört. Az alábbi példa a System.Diagnostics.CodeAnalysis.UnscopedRefAttribute metódus int M() alkalmazására, amely kijavítja a CS8170 hibát:

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();
    }
}