【问题标题】:C# - Passing functions (with arguments) as arguments of a functionC# - 将函数(带参数)作为函数的参数传递
【发布时间】:2016-11-07 11:05:50
【问题描述】:

我需要创建一个函数,它将采用另一个函数(它们的数量总是不同)。有人可以帮帮我吗?

Function DoThisFunction 会有不同类型和数量的参数。 可以有不同数量的条件函数。

我会尝试在这里展示它:

bool MyFunction(condition1(args), condition2(args), condition3(args), ... , DoThisFunction(args))
{
    ...
    if (condition1(int x) == true && condition2(int x, string C) == 5)
    {
        DoThisFunction(par1, par2, par3 ...);
        return true;
    }
}

bool condition1(int x)
{
if (x>5)
    return true;
else
    return false;
}

int condition2(int x, string C)
{
....
return par1;
}

等等……

那我需要打电话:

bool z = MyFunction(condition1(int x)==true, condition2(int x, string C)==5, DoThisFunction(par1, anotherArguments ...))

【问题讨论】:

  • 我不知道你想要达到什么目的,但我感觉你走错了路。
  • 为什么你不能简单地在外面简单地做:if (condition1 && condition2 && condition3) DoThisFunction(...);?为什么需要抽象出对所有内容的实际调用?您想在这里解决哪个问题?
  • 因为“条件”的参数是在 MyFunction 中计算的。

标签: c# function generics parameters


【解决方案1】:

我想为您的代码建议另一种方法。 也许,您可以保留一个单独的列表,其中包含您需要验证的所有功能,并在一个非常简单的循环(foreach)中运行每个方法,在这种情况下:

  • 代码会非常友好(容易理解)
  • 更好的可维护性
  • 您可以查看更少的代码并添加更多功能(例如,您可以注入一些代码,然后将另一个 Func 添加到您的 List)

请看下面的例子:

static class Program
{
    private static void Main(string[] args)
    {
        var assertions = new List<Func<object[], bool>>
        {
            Assertion1,
            Assertion2,
            Assertion3
        };

        var yourResult = Assert(assertions, 1, "1", true);
        Console.WriteLine(yourResult); // returns "True" in this case
        Console.ReadLine();
    }

    private static bool Assert(IEnumerable<Func<object[], bool>> assertions, params object[] args)
    {
        // the same as
        // return assertions.Aggregate(true, (current, assertion) => current & assertion(args));

        var result = true;

        foreach (var assertion in assertions)
            result = result & assertion(args);

        return result;
    }

    private static bool Assertion1(params object[] args)
    {
        return Convert.ToInt32(args[0]) == 1;
    }

    private static bool Assertion2(params object[] args)
    {
        return Convert.ToInt32(args[0]) == Convert.ToInt32(args[1]);
    }

    private static bool Assertion3(params object[] args)
    {
        return Convert.ToBoolean(args[2]);
    }
}

【讨论】:

    【解决方案2】:

    此解决方案似乎适用于您的问题。

    要在执行方法之前检查先决条件,请查看Code Contracts

    【讨论】:

      【解决方案3】:

      你可以像下面这样使用仿函数:

      private bool MyFunction(Func<int, bool> condition1, Func<int,string,int> condition2, Func<int,string,int, int> doThisFunction, int x, string str)
      {
          if (condition1(x) && condition2(x, str) == 5)
              return doThisFunction(x, str, x) == 10;
          return false;
      }
      

      然后在你的代码中调用这个函数,如下所示:

      MyFunction(x => x > 5 ? true : false, (x, C) => C.Length == x * 5 ? 5 : C.Length, 
                 (x, str, y) =>
                 {
                     if (x + y > str.Length)
                         return 5;
                     else if (x * y > 5)
                         return 10;
                     else
                         return 15;
                 }, 10, "Csharp");
      

      【讨论】:

      • 谢谢,这似乎有希望通过一些重载(因为函数 MyFunction 每次都需要采用不同数量的参数),但我不知道这个“lambda”(=>)是如何工作的。
      • 你可以在this link看到更多关于lambda表达式的细节。
      • 谢谢。我知道,我正在努力理解它一段时间,但我想这对我来说太过分了。
      • 我基本上想创建自己的循环,前提是我知道像“for”这样的循环是如何制作的。你可以在循环中做任何你想做的事情,调用你想要的函数。我需要的基本一样。
      猜你喜欢
      • 2019-11-21
      • 2016-01-21
      • 1970-01-01
      • 2015-03-02
      • 2021-04-13
      • 2010-11-20
      • 1970-01-01
      相关资源
      最近更新 更多