C#lamba作为方法的参数

时间:2016-04-20 09:00:47

标签: c# methods lambda delegates

在C#中是否可以让一个方法接受一个具有零个,一个或多个参数的委托?

在下面的方法中,我希望能够在对话框中单击“是”时执行其他操作。我为此使用了委托,但目前它只接受没有参数的方法。

可能有多种方法可以像传递包含参数的泛型类一样,但最好的方法是什么? C#是否能以优雅的方式提供开箱即用的东西?

    public static bool ShowCustomDialog(string message, 
                                        string caption, 
                                        MessageBoxButtons buttons,
                                        XafApplication application, 
                                        Action onYes = null)
    {
        Messaging messageBox = new Messaging(application);
        var dialogResult = messageBox.GetUserChoice(message, caption, buttons);
        switch (dialogResult)
        {
            case DialogResult.Yes:
                onYes?.Invoke();
                break;
        }
        return false;
    }

1 个答案:

答案 0 :(得分:4)

直接解决你的问题,这就是你使用lambdas的原因:

ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo, 
                 () => DoSomething(myArgument, anotherArgument));

这是依赖注入等技术的核心 - ShowCustomDialog方法不应该知道之外的任何事情,因为它不需要输入< em>来自 ShowCustomDialog 方法本身。如果ShowCustomDialog必须传递一些参数,则您使用Action<SomeType>代替Action

在幕后,编译器创建一个包含要传递的参数的类,并创建一个Target该类实例的委托。所以它(大部分)等同于手动编写这样的东西:

class HelperForTwoArguments
{
  bool arg1;
  string arg2;

  public HelperForTwoArguments(bool arg1, string arg2)
  {
    this.arg1 = arg1;
    this.arg2 = arg2;
  }

  public void Invoke()
  {
    DoSomething(arg1, arg2);
  }
}

// ...

ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo,
                 new HelperForTwoArguments(myArgument, anotherArgument).Invoke);

这个功能从一开始就在.NET框架中,它与匿名代表,特别是lambdas一起使用起来要容易得多。

但是,我不得不说我根本没有看到你的“助手”方法。与做这样的事情有什么不同?

if (ShowCustomDialog("Hi!", "Greeting", MessageBoxButtons.YesNo))
  DoSomething(myArgument, anotherArgument);