2010-06-24 100 views
11

有人可以告诉我使用委托的好处,而不是像下面所示的那样调用函数本身(或换句话说,为什么选择选项A而不是选项B)?昨天晚上我正在查看某人的linq代码,他们有类似于选项A的东西,但它被用来返回一个已编译的linq查询。Func委托与功能

我意识到前者现在可以传递给其他功能..只是不确定其实用性。顺便说一句,我意识到这不会按原样编译..在发布之前取消注释了其中一项功能。 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); 
} 

以这种方式编写函数是否有优势?

+0

可能重复的[我仍然没有得到委托](http://stackoverflow.com/questions/399222/i-still-dont-get-delegates) – 2010-06-24 19:25:30

回答

13

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

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

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

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

你传递一个委托(定义为拉姆达:item => item == "Foo")在LINQ库Where功能。这是什么使它正常工作。

3

这只有在你必须通过委托时才有用。如果您可以在编译时解析该函数​​,那么它的用处不大。

+0

你可以委托任何现有的功能在一行中,我除非你做了10,000次以上(少创建对象),否则不要认为有优势。 – Aren 2010-06-24 19:40:50

1

您可以使用代表作为“函数指针”,因此您可以将函数或“动作”赋予其他函数来执行。

什么也将与代表们感兴趣的是“预编译”的可能性,像你这样的“建”的新功能,那么这个函数返回到应用程序

2

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

4

代表的一个非常有用的功能是您可以将它们发送到任何你想要的地方。这就像在任何需要它的地方都有你的功能。一个很大的用处是事件处理。假设你有一个按钮,当用户点击这个按钮时,你需要调用任意数量的函数。如果你想到这个,有几种方法可以做到这一点:

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

OR 你可以有你想要调用(代表)的每一个的名字的公开列表,任何人都可以在任何时间,而不必知道或点击事件的所有者添加或删除这些功能甚至做任何关于他们的工作。当发生点击事件时,列表中的每个事件都会被调用并发送相同的参数,然后就完成了。

1
// 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会每次都要打电话。