【问题标题】:C# lamba as parameter to methodC# lambda 作为方法的参数
【发布时间】:2016-04-20 09:00:46
【问题描述】:

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

在下面的方法中,当我在对话框上单击“是”时,我希望能够做一些事情。我为此使用了一个委托,但目前它只接受没有参数的方法。

可能有多种方法可以做到这一点,比如传递一个包含参数的泛型类,但最好的方法是什么? 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;
    }

【问题讨论】:

  • 不,不可能创建一个接受任意数量参数的函数的方法,例如Action<T>ActionT1, T2, ...>

标签: c# methods lambda delegates


【解决方案1】:

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

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

这是依赖注入等技术的核心——ShowCustomDialog 方法不应该知道任何关于动作的内容除了,因为它不需要输入来自 ShowCustomDialog 方法本身。如果ShowCustomDialog 必须传递一些参数,您将使用Action<SomeType> 而不是Action

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

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 框架中,它更容易用于匿名委托,尤其是 lambda。

但是,我不得不说我根本看不到您的“帮助”方法有任何意义。这和做这样的事情有什么不同?

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

【讨论】:

  • 我猜 OP 需要传递具有任意数量参数的任意方法,而不仅仅是一个。所以这也应该对他有用:(x) => x.DoSomething(myArgument, anotherArgument));
  • @HimBromBeere 您将其包装在一个具有零参数的委托中——这正是我首先建议的。要么方法必须知道参数,然后允许不符合签名的委托没有意义,或者它不关心参数,然后它只需要Action .
  • 是的,这就是我现在正在寻找的东西,我可以将方法传递给 ShowCustomDialog,它不必知道它是什么类型的方法。
猜你喜欢
  • 2020-07-30
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-04
  • 1970-01-01
  • 1970-01-01
  • 2011-09-21
相关资源
最近更新 更多