Func委托与function

有人可以告诉我使用委托的优势而不是如下所示调用函数本身(或者换句话说为什么选择选项A而不是选项B)? 我昨晚看了某人的linq代码,他们有类似于Option A的东西,但它被用来返回编译的linq查询。

我意识到前者现在可以转移到其他function……只是不确定它的实用性。 顺便说一句,我意识到这不会按原样编译..在发布之前取消注释其中一个function。 TYIA

class Program { static void Main(string[] args) { Console.WriteLine(SayTwoWords("Hello", "World")); Console.ReadKey(); } // Option A private static Func SayTwoWords = (a, b) => String.Format("{0} {1}", a, b); // Option B private static string SayTwoWords(string a, string b) { return String.Format("{0} {1}", a, b); } } 

************编辑************

不确定它是否更好地解释了我的问题,但这里是一个最初让我思考这个问题的代码类型的例子:

 public static class clsCompiledQuery { public static Func<DataContext, string, IQueryable> getCustomers = CompiledQuery.Compile((DataContext db, string strCustCode) => from objCustomer in db.GetTable() where objCustomer.CustomerCode == strCustCode select objCustomer); } 

以这种方式编写函数有什么好处吗?

您发布的代码没有任何优势。 在您的代码中,使用委托只会增加复杂性以及额外的运行时成本 – 因此您最好直接调用该方法。

但是,代表们有很多用途。 “传递”到其他方法是主要用法,虽然存储函数并在以后使用它也非常有用。

LINQ完全基于这个概念。 当你这样做时:

 var results = myCollection.Where(item => item == "Foo"); 

您将委托(定义为lambda: item => item == "Foo" )传递给LINQ库中的Where函数。 这是使它正常工作的原因。

代表的一个非常有用的function是您可以将它们发送到任何您想要的地方。 就像在任何地方都需要你的function一样。 这方面的一个重要用途是事件处理。 假设您有一个按钮,当用户单击此按钮时,您希望调用任意数量的函数。 如果你考虑这个,有几种方法可以做到这一点:

你可以:调用一个调用你想要调用的其他函数的函数。 这意味着对于要调用的每个新函数,必须将其硬编码到此函数中。 很烦人。

或者您可以拥有要呼叫的每个function的名称的公共列表(代表),任何人都可以随时添加或删除这些function,而点击事件的所有者不必知道甚至做任何关于任何他们。 当click事件发生时,列表中的每个事件都会被调用并发送相同的参数,您就完成了。

它只在您必须传递委托时才有用。 如果您可以在编译时解析该函数​​,则它不太有用。

使用静态方法,您必须传递所需的所有变量。
使用委托,您可以内联您的实现并可以访问范围中的变量。

您可以将委托用作“函数指针”,这样您就可以将函数或“动作”赋予其他函数来执行。

代表们也会感兴趣的是“预编译”的可能性,就像你“构建”一个新函数然后将此函数返回给你的应用程序

 // Option A private static Func SayTwoWords = (a, b) => String.Format("{0} {1}", a, b); // Option B private static string SayTwoWords(string a, string b) { return String.Format("{0} {1}", a, b); } 

在上面的例子中,选项B是我要使用的,除非我需要改变SayTwoWordsfunction。 在选项A的情况下,可以为SayTwoWords分配不同的function。 在这个答案中捕捉更详细的差异:

选项A有意义。 考虑一种必须将表达式编译为委托的情况。 由于编译表达式很重,所以你只想做一次。 这样的模式有助于:

 public static class Cache { public static readonly Func Get = GetImpl(); static Func GetImpl() { //build expression and return compiled delegate } } 

代替

 public static class Cache { public static T Get() { //build expression, compile delegate and invoke the delegate } } 

在第一种情况下,当您调用GetGetImpl只执行一次,而在第二种情况下,(昂贵) Get将每次调用。