函数作为方法调用参数

本文关键字:调用 参数 方法 函数 | 更新日期: 2023-09-27 18:36:16

我有一个简单的问题,可能很容易回答,但大量使用谷歌并没有为我的问题带来答案。因此,如果有正确的解决方案,我深表歉意,但我没有看到它。

如果我有一个方法调用,例如

Object.Add(string text, System.Drawing.Color color);

即向具有指定颜色的某个对象添加一些文本,并且我想动态更改颜色,然后我可以键入 sth。

Object.Add("I'm a string", SomeBool ? Color.Red : Color.Green);

这非常有用,但一旦我想比较不止两种情况,就会失败。

我正在寻找的是类似(伪代码)的东西

Object.Add("I'm another string", new delegate (Sytem.Drawing.Color) 
{
    if (tristate == state.state1) 
    {
        return Color.Blue;
    } 
    else if (tristate == state2)
    {
        return Color.Green;
    }
    // ...
});

但是无论我尝试什么,它都会抛出编译器错误。

我尝试了很多关于如何将函数作为方法参数传递的谷歌,但我会发现很像

public void SomeFunction(Func<string, int> somefunction) 
{ 
    //... 
}

这不是我的问题。

谢谢:)

函数作为方法调用参数

只需将您的逻辑放在首位:

Color color;
if (tristate == state1) 
    color = Color.Blue;
else if (tristate == state2)
    color = Color.Green;
else
    color = Color.Red;
Object.Add("I'm a string", color);

您的delegate解决方案不起作用的原因很简单,new delegate (Sytem.Drawing.Color) { … }返回一个函数委托,在获取颜色值之前需要先调用该委托。而且由于您的方法需要颜色而不是返回颜色的方法,因此它并没有真正的帮助。

根据逻辑的短程度,您仍然可以在此处使用三元条件运算符并简单地链接它:

Object.Add("I'm a string", tristate == state1 ? Color.Blue : tristate == state2 ? Color.Green : Color.Red);

这将等效于上述详细的if/else if/else结构。但是,当然,它不一定更具可读性,因此请谨慎使用并选择更具可读性的解决方案。

我建议使用字典,例如

  private static Dictionary<State, Color> s_Colors = new Dictionary<State, Color>() {
    {State1, Color.Blue},
    {State2, Color.Green},
    {State3, Color.Red},
  };

  ... 
  Object.Add("I'm a string", s_Colors[tristate]);

这将允许您传递一个函数来决定状态,并将颜色传递到一个操作中,然后您可以决定如何处理该操作。实际上,文本和颜色只能在 Add 方法中使用,根本不需要返回即可使用,但这只是一个您正在寻找的示例。因为您没有使用 Add 方法中的文本(在您的示例中以任何方式),所以我将其取出,它可以在操作内部使用,否则只需将其添加回并在 Add 方法中使用它。

void Main()
{
    Object.Add(() => SomeState.State2, (col) =>
    {
        Label1.Text = "Your text";
        //Do something with color
        Label1.BackColor = col;
    });
    //example 2
    Object.Add(() => 
       {
          return someBool ? SomeState.State1 : SomeState.State2;
       }, 
       (col) =>
       {
           Label1.Text = "Your text";
           //Do something with color
           Label1.BackColor = col;
       });
}
public static class Object
{
    public static void Add(Func<SomeState> func, Action<Color> action)
    {
        switch(func())
        {
            case SomeState.State1: 
                action(Color.Blue);
                break;
            case SomeState.State2: 
                action(Color.Green);
                break;
            default: 
                action(Color.Black);
                break;
        }
    }
}
public enum SomeState
{
    State1,
    State2
}