2010-06-24 36 views
11

Ai đó có thể cho tôi biết lợi thế của việc sử dụng một đại biểu như trái ngược với việc gọi chính chức năng như hình dưới đây (hoặc nói cách khác tại sao chọn Option A trên Option B)? Tôi đã nhìn vào mã LINQ của ai đó đêm qua và họ đã có một cái gì đó tương tự như Option A nhưng nó đã được sử dụng để trả về một truy vấn LINQ đã biên dịch.Func Delegate vs Function

Tôi nhận ra rằng trước đây có thể được chuyển qua các chức năng khác .. chỉ không chắc chắn về tính thực tiễn của nó. BTW, tôi nhận ra điều này sẽ không biên dịch như-là .. uncommented một trong những chức năng trước khi gửi bài. 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); 
    }   
} 

************ EDIT ************

Không chắc chắn nếu nó giải thích câu hỏi của tôi tốt hơn nhưng đây là một ví dụ của loại mã ban đầu khiến tôi nghĩ về điều này:

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ó lợi thế nào khi viết hàm theo cách này không?

+0

bản sao có thể có của [Tôi vẫn không nhận được đại biểu] (http://stackoverflow.com/questions/399222/i-still-dont-get-delegates) –

Trả lời

13

Không có lợi thế nào trong mã bạn đã đăng. Trong mã của bạn, bằng cách sử dụng các đại biểu chỉ cần thêm phức tạp cũng như một chi phí thời gian chạy thêm - vì vậy bạn tốt hơn hết chỉ cần gọi phương thức trực tiếp.

Tuy nhiên, các đại biểu có nhiều công dụng. "Đi qua" với các phương thức khác là cách sử dụng chính, mặc dù việc lưu trữ một hàm và sử dụng nó sau này cũng rất hữu ích.

LINQ được xây dựng hoàn toàn dựa trên khái niệm này. Khi bạn làm:

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

Bạn đang đi qua một đại biểu (được định nghĩa như một lambda: item => item == "Foo") đến Where chức năng trong thư viện LINQ. Đây là những gì làm cho nó hoạt động đúng.

3

Chỉ hữu ích nếu bạn phải chuyển giao đại biểu. Nếu bạn có thể giải quyết các chức năng tại thời gian biên dịch, nó ít hữu ích.

+0

Bạn có thể ủy quyền bất kỳ chức năng hiện có nào trong một dòng, tôi không thực sự nghĩ rằng có một lợi thế trừ khi bạn đang làm nó như 10.000 lần (ít đối tượng được tạo ra). – Aren

1

bạn có thể sử dụng đại biểu làm "con trỏ hàm", vì vậy bạn có thể cung cấp chức năng hoặc "hành động" cho các chức năng khác để thực thi.

gì cũng sẽ rất thú vị với các đại biểu là khả năng "precompiling", như bạn "xây dựng" một chức năng mới và sau đó quay trở lại chức năng này để ứng dụng của bạn

2

Với phương pháp tĩnh bạn phải vượt qua trong tất cả các biến cần thiết.
Với đại biểu, bạn có thể nội tuyến việc triển khai và có quyền truy cập vào các biến trong phạm vi.

4

Một chức năng rất hữu ích của đại biểu là bạn có thể gửi cho họ bất cứ nơi nào bạn muốn. Nó giống như có chức năng của bạn ở khắp mọi nơi bạn cần nó. Một sử dụng lớn cho việc này là xử lý sự kiện. Giả sử bạn có một nút và khi người dùng nhấp vào nút này, bạn muốn bất kỳ số lượng chức năng nào được gọi. Nếu bạn nghĩ về điều này, có một vài cách bạn có thể làm điều này:

Bạn có thể: Gọi hàm có chức năng gọi cho nhau mà bạn muốn gọi. Điều này có nghĩa là đối với mỗi chức năng mới mà bạn muốn được gọi, bạn phải mã hóa nó thành hàm này. Rất phiền phức.

HOẶC Bạn có thể có một danh sách công khai tên của mỗi chức năng mà bạn muốn gọi (đại biểu), và ai cũng có thể thêm hoặc loại bỏ các chức năng này bất cứ lúc nào mà không có chủ sở hữu của sự kiện click phải biết hoặc thậm chí làm bất kỳ công việc nào liên quan đến bất kỳ công việc nào trong số họ. Khi sự kiện nhấp xảy ra, mọi sự kiện trong danh sách được gọi và gửi cùng các thông số và bạn đã hoàn tất.

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); 
} 

Trong trường hợp trên, tùy chọn B là điều tôi sẽ làm, trừ khi tôi cần thay đổi chức năng SayTwoWords. Trong trường hợp của Tùy chọn A, SayTwoWords có thể được chỉ định một chức năng khác. Nắm bắt các khác biệt chi tiết hơn in this answer:

Có tình huống trong đó Tùy chọn A có ý nghĩa. Hãy xem xét một trường hợp mà bạn phải biên dịch một biểu thức cho một đại biểu. Kể từ khi biên dịch biểu thức là nặng, đó là một cái gì đó bạn sẽ muốn làm điều đó chỉ một lần. Một mô hình như thế này giúp:

public static class Cache<T> 
{ 
    public static readonly Func<T> Get = GetImpl(); 

    static Func<T> GetImpl() 
    { 
     //build expression and return compiled delegate 
    } 
} 

thay vì

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

Trong trường hợp đầu tiên khi bạn gọi Get, GetImpl được thực hiện một lần duy nhất, nơi mà như trong trường hợp thứ hai, (đắt tiền) Get sẽ được gọi là mọi lúc.

Các vấn đề liên quan