Как я могу предотвратить освобождение объектов, созданных в al oop, в конце этой итерации цикла - PullRequest
0 голосов
/ 16 января 2020

Если я создаю объект и хочу, чтобы он длился только для текущего блока кода, после чего он будет уничтожен (или, по крайней мере, помечен для уничтожения) автоматически, я могу использовать ключевое слово scope:

using System;

class Program
{
    public void Program()
    {
        let basicString = String("Basic String");

        for (let i = 0 ; i < 4 ; i++)
        {
            let modifiedString = scope String(s);

            if (i%2 == 0)
            {
                modifiedString.ToUpper();
            }
            else
            {
                modifiedString.ToLower();
            }

            Console.WriteLine(modifiedString);

            // modifiedString is marked for destruction 
        }
    }
}

Но если мне нужно, чтобы объект оставался до окончания блока, например, для всего метода или для блока вне того, для которого он был создан, как я могу указать эту область? Например, как я могу убедиться, что строки существуют во втором l oop ниже?

using System;
using System.Collections.Generic;

class Program
{
    public void Program()
    {
        let basicString = String("Basic String");

        let modifiedStringList = scope List<String>();

        for (let i = 0 ; i < 4 ; i++)
        {
            let modifiedString = scope String(s);

            if (i%2 == 0)
            {
                modifiedString.ToUpper();
            }
            else
            {
                modifiedString.ToLower();
            }

            modifiedStringList.Append(modifiedString);
            Console.WriteLine(modifiedString);

            // somehow prevent modifiedString from being marked for destruction
        }

        modifiedStringList.RemoveAt(1);

        for (let s in modifiedStringList)
        {
            Console.WriteLine(s);
        }

        // allow all of the modifiedString to be marked for destruction here
    }
}

1 Ответ

0 голосов
/ 16 января 2020

Вы можете использовать scope::, чтобы не позволить переменной помечаться для уничтожения для всего метода:

using System;
using System.Collections.Generic;

class Program
{
    public void Program()
    {
        let basicString = String("Basic String");

        let modifiedStringList = scope List<String>();

        for (let i = 0 ; i < 4 ; i++)
        {
            // modifiedString won't be destroyed until after Program() exits.
            let modifiedString = scope:: String(s); 

            if (i%2 == 0)
            {
                modifiedString.ToUpper();
            }
            else
            {
                modifiedString.ToLower();
            }

            modifiedStringList.Append(modifiedString);
            Console.WriteLine(modifiedString);
        }

        modifiedStringList.RemoveAt(1);

        for (let s in modifiedStringList)
        {
            Console.WriteLine(s);
        }
    }
}

Если вам нужно указать произвольную область видимости между методом и текущим блоком, вы можете используйте именованный блок с BlockName: { ... } и используйте scope:BlockName:

using System;
using System.Collections.Generic;

class Program
{
    public void Program()
    {
        for (let repeat=0; repeat<10; repeat++)
        RepeatBlock:                
        {
            let basicString = String("Basic String");

            let modifiedStringList = scope List<String>();

            for (let i = 0 ; i < 4 ; i++)
            {
                // modifiedString won't be destroyed until after 
                // the block named RepeatBlock block exits.
                let modifiedString = scope:RepeatBlock String(s); 

                if (i%2 == 0)
                {
                    modifiedString.ToUpper();
                }
                else
                {
                    modifiedString.ToLower();
                }

                modifiedStringList.Append(modifiedString);
                Console.WriteLine(modifiedString);
            }

            modifiedStringList.RemoveAt(1);

            for (let s in modifiedStringList)
            {
                Console.WriteLine(s);
            }
        }
    }
}
...