【问题标题】:Func Delegate vs Function函数委托与函数
【发布时间】:2013-06-29 21:55:32
【问题描述】:

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

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

class Program
{
    static void Main(string[] args)
    {   
        Console.WriteLine(SayTwoWords("Hello", "World"));
        Console.ReadKey();
    }

    // Option A
    private static Func<string, string, string>
        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<clsCustomerEntity>>
        getCustomers = CompiledQuery.Compile((DataContext db, string strCustCode)
            => from objCustomer in db.GetTable<clsCustomerEntity>()
            where objCustomer.CustomerCode == strCustCode
            select objCustomer);
}

这样写函数有什么好处吗?

【问题讨论】:

标签: c# delegates


【解决方案1】:

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

但是,委托有很多用途。 “传递”给其他方法是主要用法,但存储一个函数并在以后使用它也非常有用。

LINQ 完全建立在这个概念之上。当你这样做时:

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

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

【讨论】:

    【解决方案2】:

    委托的一个非常有用的功能是您可以将它们发送到您想要的任何地方。这就像在您需要的任何地方都有您的功能。一个很大的用途是事件处理。假设您有一个按钮,并且当用户单击此按钮时,您希望调用任意数量的函数。如果您考虑到这一点,您可以通过以下几种方式做到这一点:

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

    您可以拥有要调用的每个函数(委托)的名称的公开列表,任何人都可以随时添加或删除这些函数,而单击事件的所有者不必知道甚至对其中任何一个进行任何工作.当点击事件发生时,列表中的每个事件都会被调用并发送相同的参数,然后就完成了。

    【讨论】:

      【解决方案3】:

      仅当您必须传递委托时才有用。如果你可以在编译时解析函数,那么它的用处就会降低。

      【讨论】:

      • 您可以在一行中委托任何现有功能,除非您执行 10,000 多次(创建的对象更少),否则我认为没有优势。
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        您可以将委托用作“函数指针”,因此您可以将函数或“动作”交给其他函数来执行。

        委托还有趣的是“预编译”的可能性,比如你“构建”一个新函数,然后将该函数返回给你的应用程序

        【讨论】:

          【解决方案6】:
          // Option A
          private static Func<string, string, string>
              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,除非我需要更改 SayTwoWords 的功能。在选项 A 的情况下,SayTwoWords 可以分配不同的功能。捕捉更详细的差异in this answer

          在某些情况下,选项 A 是有意义的。考虑一个必须将表达式编译为委托的情况。由于编译表达式很繁重,因此您只想执行一次。这样的模式会有所帮助:

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

          而不是

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

          第一种情况当你调用Get时,GetImpl只执行一次,而第二种情况,(昂贵的)Get每次都会被调用。

          【讨论】:

            猜你喜欢
            • 2013-03-13
            • 2017-11-28
            • 1970-01-01
            • 1970-01-01
            • 2018-05-10
            • 1970-01-01
            • 1970-01-01
            • 2019-09-20
            • 2021-05-31
            相关资源
            最近更新 更多