2010-06-24 101 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會每次都要打電話。