有没有办法可以将一个函数内联到一个Action委托并同时引用它?

时间:2009-06-26 03:28:32

标签: c# action self-reference inline-method

有没有办法可以内联委托任务而不是在另一个函数上分离它?

原始代码:

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

2 个答案:

答案 0 :(得分: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)赋值。我认为前者有点容易理解。

答案 1 :(得分: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
    }
}

请注意,它在初始化之前将附加字段传递给_b&lt;&gt; _1方法。