【问题标题】:how to pass a function to a function with different parameters and execute it c#如何将函数传递给具有不同参数的函数并执行它c#
【发布时间】:2018-06-26 18:40:41
【问题描述】:

我有一个 C# 应用程序。

我有几个不同的函数,它们具有不同的返回类型和传递给每个函数的不同参数。

我知道我能做到:

public object RunTheMethod(Func<string, int> myMethodName)
{
    //... do stuff
    int i = myMethodName("My String");
    //... do more stuff
    return true;
}

但我可能有 2 个要通过的函数。

第一个函数如本例所示。它接受一个字符串并返回一个 int。但是如果我想传递一个对象或根本不传递参数等怎么办?

请问这里的通用选项是什么。

谢谢

@人 我在这里有很多好的建议。这就是我喜欢这个网站的原因。我需要冷静下来,喝杯茶,仔细看看这些建议。

我保证我会回应。

谢谢大家!

【问题讨论】:

  • RunTheMethod 本身是通用的?
  • 您如何期望RunTheMethod 知道将哪些参数传递给函数?在某些情况下运行该方法是否通过和intstring 另一个?
  • @DaveShaw 嗨,我是这里的新手。泛型方法是否必须始终具有相同的签名?可以动态吗?我问这个问题的原因是我有做事的方法(显然:))并且我使用一种复杂的方式在 wpf 应用程序中显示繁忙的指示器。所以,我想我可以把我调用这个“忙碌”的方式放到这个通用函数中,然后传递这个函数来执行代码逻辑。我将有许多具有不同签名的方法。只是探索选项并希望向这里的人学习:)
  • @UnholySheep 啊,您是否建议将函数传递给函数,然后传递给函数?
  • 那么您只需要使用Action,因为您没有提供参数或使用通用工作函数的返回值。 () =&gt; MyWork(123, "Canada")

标签: c# functional-programming


【解决方案1】:

一种选择是让函数参数采用 no 参数:

public bool RunTheMethod(Func<int> f)
{
    //... do stuff
    int i = f();
    //... do more stuff
    return true;
}

然后,当调用RunTheMethod 时,您可以在 lambda 表达式中捕获其他参数,如下所示:

var b1 = RunTheMethod(() => theFunctionThatTakesAString("foo"));
var b2 = RunTheMethod(() => theFunctionThatTakesTwoIntegers(42, 1337));

如果您希望能够改变输出类型,您可以将RunTheMethod 本身设为通用,如下所示:

public bool RunTheMethod<T>(Func<T> f)
{
    //... do stuff
    T x = f();
    //... do more stuff
    return true;
}

然而,在这一点上,输入参数是一个函数是否真的有意义是一个问题。我注意到这个问题被标记为 functional-programming;那么,在 FP 中,一个更惯用的设计是简单地让方法采用 a 值:

public bool RunTheMethod<T>(T x)
{
    //... do stuff
    // no need to call a function to get x; you already have x
    //... do more stuff
    return true;
}

那么,调用方法(或函数)也变得更容易了:

var b1 = RunTheMethod(theFunctionThatTakesAString("foo"));
var b2 = RunTheMethod(theFunctionThatTakesTwoIntegers(42, 1337));

如果您需要将值作为函数,因为您希望能够控制它何时被评估,请考虑改用Lazy&lt;T&gt;

【讨论】:

  • 我认为这是函数式编程,因为我使用的是“Func”。
  • @AndrewSimpson 不,但这是一个开始:)
【解决方案2】:

你实际上需要执行任意Action而不是Func

public object RunTheMethod(Action myMethod)
{
    //... do stuff
    myMethod();
    //... do more stuff
    return true;
}

RunTheMethod(() => Sing("La la la"));

【讨论】:

    【解决方案3】:

    也许这些代码对你有帮助。

       public T Common<T>(Func<T> action)
        {
            //do something log or watch
            try
            {
                return action();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
            }
        }
    
        public Int32 Run(string query)
        {
            //Set whatever type you want. Or extend generic parameters
            return Common<Int32>(() =>
            {
                return 1;
            });
        }
    

    【讨论】:

    • 这看起来很有希望。感谢您怜悯我 :) 我现在将对此进行测试。谢谢
    • 谢谢。实际上,与我接受的答案相比,您的答案看起来不错。我需要更好地评估这一点。但是远离合同,我有一瓶酒,所以我不相信我在这里的判断。明天会好好看看..
    • 您被标记为非泛型方法作为真正的答案,但我的答案方法类型是泛型的,您可以返回任何值。
    • 感谢@AndrewSimpson :) 最好的问候。
    【解决方案4】:

    我想你想这样调用一个泛型方法:

    public object Execute(MethodInfo mi, object instance = null, object[] parameters = null)
    {
        return mi.Invoke(instance, parameters);
    }
    

    所以你的方法需要将这些作为参数。

    【讨论】:

    • 感谢您的回答。我相信这会起作用,但它看起来更像是使用反射而不是函数式编程。我在这里完全是新手,所以可能是一样的吗?
    猜你喜欢
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2023-03-08
    • 2020-01-26
    • 2015-11-30
    • 2012-10-27
    • 2018-08-04
    • 2022-01-10
    相关资源
    最近更新 更多