使扩展方法通用

时间:2010-06-12 14:35:57

标签: c#-3.0

在这个post中,有一种使用静态扩展方法更新UI线程的非常有趣的方法。

public static void InvokeIfRequired(this Control c, Action<Control> action)
{
    if(c.InvokeRequired)
    {
        c.Invoke(() => action(c));
    }
    else
    {
        action(c);
    }
}

我想做的是制作通用版本,所以我不受控件约束。这将允许我做以下例子(因为我不再局限于仅仅是一个控制)

this.progressBar1.InvokeIfRequired(pb => pb.Value = e.Progress);

我尝试了以下内容:

  public static void InvokeIfRequired<T>(this T c, Action<T> action) where T : Control
    {
        if (c.InvokeRequired)
        {
            c.Invoke(() => action(c));
        }
        else
        {
            action(c);
        }
    }

但是我得到以下错误,我不确定如何修复。有人有什么建议吗?

  

错误5无法将lambda表达式转换为类型'System.Delegate',因为它不是委托类型

3 个答案:

答案 0 :(得分:4)

替换:

c.Invoke(() => action(c));

with:

c.Invoke(action, c);

答案 1 :(得分:0)

这是一个众所周知的lambdas和匿名方法错误:

Convert this delegate to an anonymous method or lambda

您的代码只需要演员编译:

public static void InvokeIfRequired<T>(this T c, Action<T> action) where T : Control
{
    if (c.InvokeRequired)
    {
        c.Invoke((Action<T>)((control) => action(control)));
    }
    else
    {
        action(c);
    }
}

答案 2 :(得分:0)

尝试这个轻微的变化:

public static void InvokeIfRequired<T>(this T c, Action<T> action) where T : Control
{
    if (c.InvokeRequired)
    {
        c.Invoke((Action<T>)(() => action(c)));
    }
    else
    {
        action(c);
    }
}

您需要将其强制转换为委托类型。有点傻我知道。我不能真正地给你一个很好的理由为什么lambda表达式不能隐式赋值为委托。