我什么时候应该使用C#Generic Func <t,tresult>?

时间:2015-07-11 15:50:41

标签: c# generics func

我一直在关注C#的通用函数委托(Func)功能。

示例:

// Instantiate delegate to reference UppercaseString method
Func<string, string> convertMethod = UppercaseString;
string name = "Dakota";

// Use delegate instance to call UppercaseString method
Console.WriteLine(convertMethod(name));

我正在努力想到一个真实的场景,它们可能在我自己的应用程序中很有用。所以我想我会把问题提到那里。 \

我非常感谢你的想法。

2 个答案:

答案 0 :(得分:7)

假设需要为方法调用时间方法调用。由于维护原因,将定时代码放在函数内部是不可行的。

因此,通过使用Func调用,可以执行时间操作而不会干扰:

static void Time<T>(Func<T> work)
{
    var sw = Stopwatch.StartNew();
    var result = work();
    Console.WriteLine(sw.Elapsed + ": " + result);
}

然后用我们的函数调用它来定时

Time(() => { return "Jabberwocky"; });

结果:

 00:00:00.0000926: Jabberwocky

以下是使用相同时间主题的Funct<T,TResult>使用时间正则表达式与string.split

的示例用法
var strData = "The rain in Spain";

Time((str) => { return Regex.Split(str, @"\s"); }, strData);
Time((str) => { return str.Split(); },             strData);

这是设置

static void Time<T,S>(Func<T,S> work, T strToSplit)
{
   var sw = Stopwatch.StartNew();
   var result = work(strToSplit);
   sw.Stop();

    var joined = string.Join(", ", result as string[]);
    Console.WriteLine("{0} : {1}", sw.Elapsed, joined);

}

结果

00:00:00.0000232 : The, rain, in, Spain
00:00:00.0000021 : The, rain, in, Spain

2017年更新此答案。这不是Func,而是非返回兄弟Action;我发现我在我的类上执行了一种基本形式的登录,我使用来自消费者的依赖注入

Action<string> ReportIt  { get; set; }

public void ReportStatus(Action<string> statusReporter)
{
    ReportIt = statusReporter;   
}

这个想法是状态报告是可选的,所以稍后在代码中我会检查它是否是vialble,如果是,我给出了状态:

 ReportIt?.Invoke("Running - Connection initiated");

该类的使用者将其称为

 piperInstance.ReportStatus( Console.WriteLine );

也可以表示为

 piperInstance.ReportStatus((str) => { Console.WriteLine(str); } );

答案 1 :(得分:1)

评论有点长(制作社区维基)

解释用例的最佳方法是使用函数map

在C#中称为Select

假设您有一个字符串列表,map将允许您更改字符串。

如你所示:

somewords.Select(Uppercase)

somewords.Select(x = Uppercase(x))

somewords.Select(x => x.ToUpper())

但它不仅限于字符串到字符串的转换。假设您想获得所有字符串长度的列表,您可以简单地执行:

somewords.Select(x => x.Length)

上面将返回一个整数列表(或您的语言中使用的任何内容)。

一旦你开始将它与其他高阶函数结合起来,事情变得有趣:)

回到上一个例子,但是说你想要最长字符串的长度。你有很多选择:

somewords.Select(x => x.Length).Max()
somewords.OrderByDescending(x => x.Length).First()
// or even
somewords.Max(x => x.Length)

可能还有一些我错过了。最后,它可以帮助您表达您的意图,而无需进行大量额外工作(如最后一个示例)。

注意:

在上面的每一个案例中,x => x.Length都可以替换为与获取长度相同的任何函数,例如Foo。例如

int Foo(string s)
{
  return s.Length;
}

所以somewords.Max(Foo)是一样的。