Проблема с делегатами в C#

Если Вы удаляете новый от Вашего кода, Вы добираетесь:

предупреждение CS0108: 'Панель. Сделайте ()', скрывает наследованного участника 'Нечто. Сделайте ()'. Используйте новое ключевое слово, если сокрытие было предназначено.

компилятор C# просто предупреждает Вас, что Вы могли бы делать что-то, что Вы не предназначали и просите, чтобы Вы вставили новый ключевое слово, чтобы подтвердить, что Вы знаете то, что Вы делаете. Помимо подавления предупреждения, это не имеет никаких других эффектов.

7
задан recursive 2 November 2009 в 11:10
поделиться

4 ответа

Проблема в том, что вы захватываете одну и ту же переменную i в каждом делегате, которая к концу цикла просто имеет значение 5.

Вместо этого, вы хотите, чтобы каждый делегат захватил другую переменную, что означает объявление новой переменной в цикле:

for (int i = 0; i < 5; ++i)
{
    int localCopy = i;
    methods.Add(delegate(object obj) { return DummyMethod(localCopy); });
}

Это довольно распространенная ошибка - вы можете прочитать немного больше о захваченных переменных и замыканиях в моей статье о замыканиях .

17
ответ дан 6 December 2019 в 06:36
поделиться

Если вы посмотрите на сгенерированный код (с использованием Reflector), вы увидите разницу:

private static void Method2()
{
    List<Methodx> list = new List<Methodx>();
    Methodx item = null;
    <>c__DisplayClassa classa = new <>c__DisplayClassa();
    classa.i = 0;
    while (classa.i < 5)
    {
        if (item == null)
        {
            item = new Methodx(classa.<Method2>b__8);
        }
        list.Add(item);
        classa.i++;
    }
    foreach (Methodx methodx2 in list)
    {
        Console.WriteLine("In main method c = " + methodx2(null));
    }
}

Когда вы используете исходный код, он создает временный класс в фоновом режиме, этот класс содержит ссылку к переменной "i", поэтому, согласно ответу Джона, вы видите только окончательное значение этого.

private sealed class <>c__DisplayClassa
{
    // Fields
    public int i;

    // Methods
    public <>c__DisplayClassa();
    public int <Method2>b__8(object obj);
}

Я действительно рекомендую посмотреть код в Reflector , чтобы увидеть, что происходит, как я это сделал смысл захваченных переменных. Убедитесь, что для параметра «Оптимизация кода» выбрано значение «.NET 1.0» в меню «Параметры», в противном случае все скрытые элементы скроются.

4
ответ дан 6 December 2019 в 06:36
поделиться

Эта статья, вероятно, поможет вам понять, что происходит (т.е. что такое закрытие ): http://blogs.msdn.com/oldnewthing/archive /2006/08/02/686456.aspx inventory

4
ответ дан 6 December 2019 в 06:36
поделиться

Я думаю, это потому, что переменная i положить в кучу (это 'sa захваченная переменная )

Взгляните на этот ответ .

2
ответ дан 6 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: