【问题标题】:Use method with more arguments as an action with less [duplicate]使用具有更多参数的方法作为具有更少[重复]的操作
【发布时间】:2019-05-20 03:14:37
【问题描述】:

我想使用这样的方法:

public void A(Action<Action<string>> x)
{
    for (int i = 0; i < 10; i++)
    {
        x.Invoke(data => {
             Console.WriteLine($"{data} --- {i}");
        });
    }
}

这里的想法是,(此方法的)用户将输入另一个方法,该方法可以从偏好的数据源生成字符串。
假设我想为用户提供一些内置解决方案作为静态方法:

public void B(string fileName, Action<string> y)
{
     // process fileName
     string data = C(fileName);
     // invoke inner action
     y.Invoke(data);
}

用例是:

A(B("/home/user1"));

问题在于 B 仍然需要为 fileName 提供另一个参数
我该怎么做?

【问题讨论】:

  • 旁注:你为什么要.Invoke 而不是像x(data =&gt;...) 这样称呼它?
  • 这只是个人喜好

标签: c# .net-core asp.net-core-2.1


【解决方案1】:

我在打字的时候就知道了...
我真正需要使用的是Func&lt;T&gt;,而不是Action&lt;Action&lt;T&gt;&gt;
示例:

public void A(Func<string> x)
{
    for (int i = 0; i < 10; i++)
    {
        var data = x.Invoke();
        Console.WriteLine($"{data} --- {i}");
    }
}

public string B(string fileName)
{
     // process fileName
     string data = C(fileName);
     return data;
}

public void Main()
{
    A(B("home/user1"));
}

我不能只是将string 传递给A,由B 生成,例如:

public void A(string data)

因为这不允许更改 B 中的数据源(B 可以根据其他参数更改源 - 例如,如果 B 选择了前缀为 fileName 的随机文件)

编辑:这仍然行不通!问题是通过调用B,我们肯定不会将B 作为参数传递,而是B 的返回类型。
在我的情况下,B 输入源的更改是无关紧要的,适当的解决方案是将B 更改为:

public IEnumerable<string> B(string fileName)
{
    foreach (var line in File.ReadAllLines("fileName"))
    {
         yield return line;
    }
}

【讨论】:

  • 这似乎没有回答问题 - 你已经开始使用返回方法的方法,但将其更改为其他东西......问题似乎是关于正确的柯里化......跨度>
  • 是的,我意识到给定的示例与我的实际用例不匹配。这是为了 NN 顺便说一句。
  • @AlexeiLevenkov 你会这样做吗? gist.github.com/Mitiko/c1f361affeb9ac9b4698dbb04b3a8611
  • 可能不会...目前尚不清楚您想要实现什么...但是当人们经常走这么长的路时,目标是进行惰性评估 - 所以我不会让调用者提前调用任何函数(与您的 B("home/user1") 不同,但让他们按照我选择的副本 - A(Apply(B, fileName)) 所示进行部分应用)
猜你喜欢
  • 1970-01-01
  • 2013-03-13
  • 2018-12-29
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
相关资源
最近更新 更多