从表单调用方法

P.B*_*key 1 c# winforms

是否可以使用表单中的参数调用方法?我知道我可以使用一个动作.我认为闭包捕获动作中的变量以允许它工作.不过,我觉得方法会更清洁.我在代码库中有很多这些动作,我不喜欢它们隐藏在难以重构的方法内部.

    public static void Main()
    {
        Form form = new Form();
        Action action = () => form.SendToBack();//(Now Imagine this Action is 50 lines of code and there's 15 of them...Then it should make sense as to why I want to seperate this logic out into classes and methods.
        //Action action2 = AMethod(form);//doesnt work

        Task.Factory.StartNew(
            () =>
            {                    
                //form.Invoke(AMethod);//doesnt work see error below...also no params
                form.Show();                    
                form.Invoke(action);
                Application.Run();
            }
         );
        Console.Read();
    }

    public static void AMethod(Form form)
    {
        form.SendToBack();
    }
Run Code Online (Sandbox Code Playgroud)

更新
我根据评论尝试了重载form.Invoke(AMethod,form);,我得到错误:

参数1:无法从'方法组'转换为'System.Delegate'

Han*_*ant 6

Control.Invoke()的重载是:

  public Object Invoke(Delegate method)
  public Object Invoke(Delegate method, params Object[] parameters)
Run Code Online (Sandbox Code Playgroud)

第一个参数类型是麻烦制造者,Delegate是一种"无类型"委托类型.C#编译器坚持使用类型化的委托,以便它可以验证您是否正在使用正确的签名调用方法.在您的情况下,这意味着您必须传递类型的委托对象Action<Form>.要求它仅从方法"组"推断委托类型是它不会做的.有点烦人,但类型安全在C#中至关重要.

所以正确的语法是:

  form.Invoke(new Action<Form>(AMethod), form);
Run Code Online (Sandbox Code Playgroud)

哪个没有赢得任何奖品.很难传递捕获表单变量的lambda语法:

   form.Invoke(new Action(() => AMethod(form)));
Run Code Online (Sandbox Code Playgroud)

匿名方法也有效,但您必须为同样的原因进行强制转换:

   form.Invoke((Action)delegate { AMethod(form); });
Run Code Online (Sandbox Code Playgroud)