【问题标题】:C# extension using function Func as parameter使用函数 Func 作为参数的 C# 扩展
【发布时间】:2016-09-25 11:29:43
【问题描述】:

请不要与代码混淆,代码是错误的。专注于下面的粗体问题。

我一直在准备学习函数式编程,至少要为它的先决条件做好准备,我一直在研究扩展、函数和 lambda 表达式。

下面的代码不起作用我只是认为应该这样编码:

程序:

class Program
{
    static void Main(string[] args)
    {
        int s = 10;
        int t = s.CreatedMethod(2, 3); // <-- the one that calls the extension
        Console.WriteLine(t.ToString());
        Console.ReadLine();
    }


    static int RegularMethod(int v1, int v2)
    {
        return v1 * v2; // <-- I also wanted to multiply int 's' like this s*v1*v2
    }
}

扩展名:

public static class Extension
{
    public static int CreatedMethod(this int number, Func<int, int, int> fn) 
    { 
       // I'm expecting that the code here will read the 
       // RegularMethod() above
       // But I don't know how to pass the parameter of the function being passed
       return @fn(param1, param2)// <-- don't know how to code here ??
    } 
}

如您所见,CreateMethod 扩展了我的整数“s”。我的计划是在上面的 CreateMethod() 中传递两个参数并将这两个参数乘以 's'

在上面的例子中,答案应该是 60。

你能帮我使用扩展程序吗?

【问题讨论】:

  • Func&lt;int, int, int&gt; 接受 2 个输入参数并返回 int。所以要调用它,你应该是fun(param1, param2)。您的扩展只需要一个参数(fn 除外)。因此,您需要在 CreatedMethod 中添加其他参数。
  • @DovydasSopa 是的,你说得对,我忘了包括它。但即使我这样做。我将在哪里获得 param1 和 param2?查看代码。
  • 首先不清楚你是否想要Func&lt;int, int, int&gt;。如果您打算传递数字,为什么要这样声明?
  • 是的,我也想知道 - 你为什么要传递一个函数?你想做什么?
  • 你要不要s.CreatedMethod(2, 3, RegularMethod)?目前尚不清楚您为什么要这样做,除非CreatedMethod 也在做其他事情......

标签: c# functional-programming extension-methods func chaining


【解决方案1】:

这可能是您正在寻找的,但是将函数作为参数传递是没有意义的,或者我可能只是遗漏了一些东西。无论如何,它有效:

class Program
{
    static void Main(string[] args)
    {
        int s = 10;
        // the function we're passing as a parameter will multiply them
        // then return the result
        int t = s.CreatedMethod((param1, param2) => param1 * param2);
        // or you can use this since the method signature matches:
        // int t = s.CreatedMethod(RegularMethod);
        Console.WriteLine(t.ToString()); // outputs "60"
        Console.ReadLine();
    }

    static int RegularMethod(int v1, int v2)
    {
        return v1 * v2; // <-- I also wanted to multiply int 's' like this s*v1*v2
    }
}

public static class Extension
{
    public static int CreatedMethod(this int number, Func<int, int, int> fn)
    {
        return number * fn.Invoke(2, 3);
    }
}

跟进 OP 的评论:如果您不想硬编码这些值,则需要将 CreateMethod 的签名更改为:

public static int CreatedMethod(this int number, int val1, int val2, Func<int, int, int> fn) 

然后像这样调用Invoke

fn.invoke(val1, val2)

【讨论】:

  • 我认为 OP 正试图通过 Funcint 参数...不知道为什么,但你去了。
  • 嗨 Nasreddine 这个代码 --> fn.Invoke(2, 3) .. 这是硬编码的吧?我可能也会改变它。?
  • 是的,它们是硬编码的,除非您将 CreateMethod 更改为 public static int CreatedMethod(this int number, int val1, int val2, Func&lt;int, int, int&gt; fn),然后使用 fn.invoke(val1, val2) 调用调用
【解决方案2】:

扩展可能如下所示:

public static int CreatedMethod(this int number1, int number2, Func<int, int, int> fn) {
    fn(number1, number2);
}

然后调用将是:

var s = 10;
var t = s.CreatedMethod(2, RegularMethod).
    CreatedMethod(3, RegularMethod);

这将首先使用102 调用RegularMethod,第二次使用203

其他方法是使用扩展名

public static int CreatedMethod(this int number1, int number2, int number3, Func<int, int, int> fn) {
    fn(fn(number1, number2), number3);
}

然后打电话

var s = 10;
var t = s.CreatedMethod(2, 3, RegularMethod);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 2019-09-20
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 2021-12-07
    相关资源
    最近更新 更多