CS8352-ös fordítási hiba

Ebben a kontextusban a változó nem használható, mert a hivatkozott változókat a deklarációs hatókörön kívül is elérhetővé teheti.

Ez a hiba a lehetséges nem definiált viselkedést jelzi, ha fennáll a veszélye annak, hogy a verem által lefoglalt változót már törölték a veremből.

A hiba kijavítása

CS8352 Kijavíthatja, ha biztosítja, hogy a változó hatóköre legalább olyan széles legyen, mint a rá hivatkozó változó. Ezt úgy teheti meg, hogy a tárterületet egy halomra vagy a hívókörnyezetben lévő verembe helyezi.

Példa

A következő minta a CS8352-t hozza létre:

class Program
{
    static public Span<int> CreateSpanWithValue(int size, int value)
    {
        Span<int> localSpan = stackalloc int[size];
        localSpan[0] = value;
        return localSpan;    // CS8352
    }                        // localSpan refers to stack memory that's been reclaimed.

    static public void Main()
    {
        Span<int> localSpan = CreateSpanWithValue(5, 10);
        localSpan[2] = 14;
        foreach(var item in localSpan)
        {
            Console.WriteLine(item.ToString());  // Reading from deleted object
        }
    }
    // Example of output:
    // 284945320
    // 149
    // 149
    // 1369466325
    // 284945320
}

Az alábbi minta áthelyezi a veremfoglalást, hogy a hatóköre megegyezik a Span.
Ez a példamegoldás azért működik, mert a memóriafedél arra hivatkozik, hogy a veremen van lefoglalva, de a hívó környezetben:

class Program
{
    static public void FillSpanWithValue(Span<int> span, int value)
    {
        span[0] = value;
    }

    static public void Main()
    {
        Span<int> localSpan = stackalloc int[5];
        FillSpanWithValue(localSpan, 10);
        localSpan[2] = 14;
        foreach(var item in localSpan)
        {
            Console.WriteLine(item.ToString());
        }
    }
    // Output:
    // 10
    // 0
    // 14
    // 0
    // 0
}

Az alábbi minta a new kulcsszóval hozza létre az objektumot halom helyett.
Ez a példamegoldás működik, mert a metódusból CreateSpanWithValue való visszatérés után a Span által hivatkozott memória továbbra is érvényes, mivel a halomra van lefoglalva, nem pedig veremen:

class Program
{
    static public Span<int> CreateSpanWithValue(int size, int value)
    {
        Span<int> localSpan = new int[size];
        localSpan[1] = value;
        return localSpan;
    }

    static public void Main()
    {
        var span = CreateSpanWithValue(5, 10);
        span[2] = 14;
        foreach(var item in span)
        {
            Console.WriteLine(item.ToString());
        }
    }
    // Output:
    //0
    //10
    //14
    //0
    //0
}

Lásd még