Func委托现实世界的使用
我最近一直在使用委托 Func
并创建返回包含 lambda 的不同实例 Func
的方法,但我一直在努力提出的是任何关于为什么人们想要返回(甚至创建这样一个实例)的现实世界的好想法。
MSDN 上有一个示例,他们执行以下操作...
Func<string, string> convertMethod = UppercaseString;
private static string UppercaseString(string inputString)
{
return inputString.ToUpper();
}
并且尽管它看起来很漂亮并且是一个有趣的概念,但我看不出这样的代码提供了什么优势。
那么,这里有人可以提供任何现实世界中他们必须使用 Func
I've recently been playing around with the delegate Func<T, TResult>
and creating methods that return different instances Func<T, TResult>
containing lambda but what I have struggled to come up with is any good real world ideas of why one might want to return (or even create such an instance).
There is an example on MSDN where they do the following...
Func<string, string> convertMethod = UppercaseString;
private static string UppercaseString(string inputString)
{
return inputString.ToUpper();
}
And although it looks pretty and is an interesting concept I fail to see what advantages such code provides.
So could someone here please provide any real world examples where they have had to use Func<T, TResult>
and in general why one might want to use this delegate?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果您真正问的是为什么我们一般都有委托:
IQueryable
提供程序(您使用了表达式,但对于 LINQ-to-Objects,您使用了委托)委托提供了一种将您自己的行为注入到另一个对象中的方法。最常见的用法是与事件一起使用。对象公开一个事件,并且您提供一个函数(无论是否匿名),该函数在该事件触发时被调用。
如果您问为什么我们有
Func
(和类似的)委托,那么有两个主要原因:Action<>
和Func<>
委托无法涵盖所有情况,但它们提供起来很简单,并且涵盖了许多需要自定义代表的情况。Func
委托在 LINQ-to-Objects 中广泛用于定义谓词。更具体地说,Func
。这允许您定义一个谓词,该谓词采用 IEnumerableIf what you're asking, really, is why we have delegates in general:
IQueryable
provider you've used an expression, but for LINQ-to-Objects you've used a delegate)Delegates provide a way of injecting your own behavior into another object. The most common usage is with events. An object exposes an event and you provide a function (anonymous or not) that gets called when that event fires.
If you're asking why we have the
Func<T, TResult>
(and similar) delegate, then there are two main reasons:Action<>
andFunc<>
delegates can't cover all cases, they are simple to provide and cover many of the cases where custom delegates were needed.Func<T, TResult>
delegate is used extensively in LINQ-to-Objects to define predicates. More specifically,Func<T, bool>
. This allows you to define a predicate that takes a strongly-typed member of anIEnumerable<T>
and returns a boolean by using either a lambda or ordinary function, then pass that predicate to LINQ-to-Objects.您会在 LINQ 中经常使用它。例如,将列表中的所有数字加倍:
这是一个
Func
。创建简洁的代码时它非常有用。一个现实世界的例子是在我制作的众多塔防游戏之一中,我使用一行计算了距离塔最近的敌人:You would use it a lot in LINQ. So, for example, to double all the numbers in a list:
That's a
Func<TIn, TOut>
. It's quite useful when creating concise code. A real-world example is in one of the many tower-defence games I made, I calculated the closest enemy to the tower using one line:我认为一个很好的例子是延迟初始化。
I think a great example is lazy initialization.
需要函数指针的典型示例是将比较函数传递给排序例程。为了具有不同的排序键,您可以为比较函数创建一个 lambda,并将其传递给排序函数。
或者举一个简单的现实示例:
在此示例中,
cust => cust.LastName == lastName
不仅仅是一个 lambda,它还通过捕获lastName
参数创建一个闭包。换句话说,它创建一个函数,每次调用FindByLastName
时该函数都会不同。The canonical example of a need for a function pointer is for a comparison function to pass to a sort routine. In order to have different sort keys, you create a lambda for the comparison function, and pass that to the sort function.
Or for a simple real-world example:
In this example,
cust => cust.LastName == lastName
is not just a lambda, but it creates a closure by capturing thelastName
parameter. In othe words, it creates a function, which will be different every timeFindByLastName
is called.Func
委托(和其他重载)为您提供了在 C# 中编写抽象的新方法。为了演示一些选项,这里有几个可以使用委托编写的 C# 语言构造:这些构造非常原始,因此最好为它们提供一个语言构造。然而,它表明
Func
和 lambda 表达式增加了相当多的表达能力。它使得编写新的构造成为可能,例如并行循环(使用.NET 4.0):The
Func<T>
delegate (and other overloads) give you new ways for writing abstractions in C#. To demonstrate some of the options, here are a couple of C# langauge constructs that could be written using delegates instead:These are quite primitive, so it is good to have a language construct for them. However, it demonstrates that
Func
and lambda expressions add quite a lot of expressive power. It makes it possible to write new constructs such as parallel loop (using .NET 4.0):首先,
Func
不是一个类,它是一个委托。基本上,如果您不想为此声明自己的委托,则只要需要方法参数或委托类型的属性,就可以使用它。
First of all,
Func<T>
is not a class, it's a delegate.Basically, you can use it whenever you need a method argument or a property of delegate type if you don't want to declare your own delegate for that.
除了嵌入到许多框架(例如 LINQ、模拟工具和依赖注入容器)中这一事实之外,
Funct
的一大用途是使用它来创建 基于委托的工厂。One great use of
Funct<T>
, besides the fact that it is embedded in many frameworks such as LINQ, Mocking Tools, and Dependency Injection containers is to use it to create a delegate based factory.最近,我希望调用我的方法的外部程序能够修改它的行为方式。
我的方法本身只是将文件从 XLS 转换为 XML。但有必要允许调用代码在需要时指定任意数量的转换,这些转换应在写入为 xml 标记之前应用于每个 xls 单元格。例如:将“,”小数分隔符转换为“.”,抑制千位分隔符等等(转换都是字符串替换)。
然后,调用者代码只需在字典中添加任意数量的条目,其中键是模式,值是该模式的替换字符串。我的方法循环遍历字典并为每个条目创建一个新的
Func
。然后对于每个单元格,按顺序应用Func
。Recently, I wanted the external program calling my method to be able to modify the way it behaves.
My method in itself simply converts a file from XLS to XML. But it was necessary to allow the calling code to specify if needed an arbitrary number of transformations which should apply to each xls cell before being writing as a xml tag. For example : convert the "," decimal separator to ".", suppress the thousand separator, and so on (the transformations were all string replacements).
Then the caller code just had to add an arbitrary number of entries in a dictionary where the key is the pattern and the value is the replacement string for this pattern. My method loops over the dictionary and creates a new
Func<string,string>
for each entry. Then for each cell theFunc<string,string>
are applied in sequence.