Есть ли способ, которым я могу встроить функцию в делегат Action и ссылаться на нее одновременно?

2

Есть ли способ, которым я могу встроить делегированную задачу, а не разделять ее на другую функцию?

Оригинальный код:

    private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
    {            
        System.Threading.ThreadPool.QueueUserWorkItem((o) => Attach());
    }

    void Attach() // I want to inline this function on FileOk event
    {

        if (this.InvokeRequired)
        {
            this.Invoke(new Action(Attach));
        }
        else
        {
            // attaching routine here
        }
    }

Я хотел, чтобы это было так (нет необходимости создавать отдельную функцию):

    private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
    {

        Action attach = delegate
        {
            if (this.InvokeRequired)
            {
                // but it has compilation here
                // "Use of unassigned local variable 'attach'"
                this.Invoke(new Action(attach)); 
            }
            else
            {
                // attaching routine here
            }
        };

        System.Threading.ThreadPool.QueueUserWorkItem((o) => attach());
    }
Теги:
action
self-reference

2 ответа

4
Лучший ответ

Я думаю, что это сработает:

private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
{

    Action attach = null;
    attach = delegate
    {
        if (this.InvokeRequired)
        {
            // since we assigned null, we'll be ok, and the automatic
            // closure generated by the compiler will make sure the value is here when
            // we need it.
            this.Invoke(new Action(attach)); 
        }
        else
        {
            // attaching routine here
        }
    };

    System.Threading.ThreadPool.QueueUserWorkItem((o) => attach());
}

Все, что вам нужно сделать, это присвоить значение "attach" (null works) перед строкой, объявляющей анонимный метод. Я думаю, что первое немного легче понять.

  • 0
    спасибо, это работает ^ _ ^ это просто немного сбивает с толку, почему C # обнаружил его как неназначенный
  • 0
    Во время выполнения правая часть назначения оценивается перед левой частью. Следовательно, часть компилятора, отвечающая за это предупреждение, вероятно, видит, что мы пытаемся использовать значение переменной в правой части выражения в строке, которую мы ему присвоили, следовательно, во время оценки RHS она еще не было назначено Конечно, так как компилятор собирается поднять его в замыкание, все равно все будет в порядке - я думаю, что компилятор не знает, как он собирается изменить его, когда выдает предупреждение.
0

Причина, по которой вы получаете ошибку "использование непризнанной переменной", объясняется тем, как компилятор действительно генерирует код. Когда вы используете синтаксис delegate {}, реальный метод создается для вас компилятором. Поскольку вы ссылаетесь на прикрепленное поле в своем делете, компилятор пытается передать локальную переменную attach в сгенерированный метод делегата.

Здесь грубо переведенный код, который должен помочь сделать его более ясным:

private void ofdAttachment_FileOk(object sender, CancelEventArgs e)
{

    Action attach = _b<>_1( attach );

    System.Threading.ThreadPool.QueueUserWorkItem((o) => attach());
}

private Action _b<>_1( Action attach )
{
    if (this.InvokeRequired)
    {
        // but it has compilation here
        // "Use of unassigned local variable 'attach'"
        this.Invoke(new Action(attach)); 
    }
    else
    {
        // attaching routine here
    }
}

Обратите внимание, что перед передачей этого поля передается поле attach в метод _b < > _.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню