2010-01-11 123 views
123

Tôi bối rối rằng vai trò thực sự của một đại biểu là gì? Tôi đã được hỏi câu hỏi này nhiều lần trong các cuộc phỏng vấn của mình, nhưng tôi không nghĩ rằng những người phỏng vấn hài lòng với câu trả lời của tôi.Đại biểu là gì?

Bất cứ ai có thể cho tôi biết định nghĩa tốt nhất, trong một câu, với một ví dụ thực tế?

Cảm ơn

+18

tò mò, bạn đã phản hồi như thế nào để chúng tôi có thể cho bạn biết cách bạn có thể sửa nó? –

Trả lời

140

Tôi thích nghĩ đến đại biểu là "con trỏ đến hàm". Điều này quay trở lại C ngày, nhưng ý tưởng vẫn còn giữ.

Ý tưởng là bạn cần để có thể gọi một đoạn mã, nhưng đoạn mã mà bạn sắp gọi sẽ không được biết cho đến khi chạy. Vì vậy, bạn sử dụng một "đại biểu" cho mục đích đó. Các đại biểu có ích cho những thứ như trình xử lý sự kiện và như vậy, nơi bạn làm những việc khác nhau dựa trên các sự kiện khác nhau, chẳng hạn.

Here's một tài liệu tham khảo cho C# bạn có thể xem xét:

Trong C#, ví dụ, giả sử chúng ta có một tính toán, chúng tôi muốn làm và chúng tôi muốn sử dụng một phương pháp tính toán khác nhau mà chúng ta không biết cho đến khi thời gian chạy. Vì vậy, chúng ta có thể có một phương pháp vài tính như thế này:

public static double CalcTotalMethod1(double amt) 
{ 
    return amt * .014; 
} 

public static double CalcTotalMethod2(double amt) 
{ 
    return amt * .056 + 42.43; 
} 

Chúng ta có thể khai báo một chữ ký đại biểu như thế này:

public delegate double calcTotalDelegate(double amt); 

Và sau đó chúng ta có thể khai báo một phương pháp trong đó có các đại biểu như một tham số như thế này :

public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal) 
{ 
    return calcTotal(amt); 
} 

Và chúng tôi có thể gọi phương thức CalcMyTotal bằng phương thức đại biểu mà chúng tôi muốn sử dụng.

double tot1 = CalcMyTotal(100.34, CalcTotalMethod1); 
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2); 
Console.WriteLine(tot1); 
Console.WriteLine(tot2); 
+17

+1 cho cái gật đầu với con trỏ hàm đơn giản nhưng hiệu quả trong C. –

+3

Một câu hỏi liên quan đến câu trả lời của bạn. Làm thế nào nó thực sự khác với việc gọi một hàm theo cách thông thường? Chỉ vì nó không được biết trong thời gian chạy? – NAVEED

+0

@NAVEED - tham khảo bản chỉnh sửa mới nhất của tôi, tôi đã đưa ra một ví dụ. Theo như lời gọi phương thức thực tế, nó không khác gì so với lời gọi phương thức thông thường trong ví dụ trên của tôi (hàm calcTotal (gọi) là đại biểu), nhưng sức mạnh của các đại biểu là bạn có thể sử dụng chúng làm tham số, v.v. khi bạn muốn một phương pháp để có thể có hành vi khác nhau. Có nhiều thứ khác bạn có thể sử dụng chúng, đây chỉ là một ví dụ đơn giản. Hy vọng rằng sẽ giúp. – dcp

16

đại biểu chỉ đơn giản là con trỏ hàm.
chỉ cần đặt bạn chỉ định phương thức bạn muốn chạy đại biểu của mình. sau đó trong mã, bạn có thể gọi phương thức đó thông qua Gọi.

một số mã để chứng minh (viết này từ bộ nhớ để cú pháp có thể được tắt)

delegate void delMyDelegate(object o); 

private void MethodToExecute1(object o) 
{ 
    // do something with object 
} 

private void MethodToExecute2(object o) 
{ 
    // do something else with object 
} 

private void DoSomethingToList(delMyDelegate methodToRun) 
{ 
    foreach(object o in myList) 
     methodToRun.Invoke(o); 
} 

public void ApplyMethodsToList() 
{ 
    DoSomethingToList(MethodToExecute1); 
    DoSomethingToList(MethodToExecute2); 
} 
4

Hãy suy nghĩ về delegate như về việc thực hiện đơn giản hóa các mẫu Command.

13

Taken from here

Q đại biểu là gì?
A Khi một đối tượng nhận được yêu cầu, đối tượng có thể tự xử lý yêu cầu hoặc chuyển yêu cầu đến đối tượng thứ hai để thực hiện công việc. Nếu đối tượng quyết định chuyển yêu cầu, bạn nói rằng đối tượng đã chuyển tiếp trách nhiệm xử lý yêu cầu cho đối tượng thứ hai.

Hoặc, như một ví dụ giả dễ dàng: điều gì đó gửi yêu cầu đến đối tượng1. object1 sau đó chuyển tiếp yêu cầu và chính nó tới object2 - delegate. object2 xử lý yêu cầu và thực hiện một số yêu cầu.(Lưu ý: liên kết ở trên đưa ra ví dụ tốt)

+0

Ví dụ được đưa ra trong liên kết ở trên không cho biết chính xác ủy quyền. –

-1

Trong khi không phải thực sự là một "con trỏ hàm", một đại biểu có thể trông như thế này là một ngôn ngữ động như PHP:

 


$func = 'foo'; 
$func(); 

function foo() { 
    print 'foo'; 
} 
 

hoặc bằng JavaScript bạn có thể làm một cái gì đó như :

 

var func = function(){ alert('foo!'); } 
func(); 
 
+2

Đây không phải là ví dụ về phái đoàn. Trong ví dụ của bạn, bạn đang sử dụng hàm được gọi là hàm biến mà về cơ bản tìm một hàm có cùng tên với chuỗi mà biến tham chiếu. Xem các chức năng biến: http://php.net/manual/en/functions.variable-functions.php – Aquarelle

1

Giải thích tuyệt vời và triển khai thực tiễn mẫu đại biểu có thể tìm thấy trong các lớp học của Bộ sưu tập Google Forwarding (cũng là mẫu trang trí).

1

Trong người gửi thông tin sự kiện không biết đối tượng nào sẽ xử lý sự kiện. Ủy quyền là loại giữ tham chiếu phương thức. Đại biểu có chữ ký và giữ tham chiếu đến phương thức khớp với chữ ký của nó để Ủy quyền giống như loại con trỏ chức năng an toàn.

button1.Click + = new System.EventHandler (button1_Click) System.EventHandler được khai báo là một đại biểu ở đây Trong Sự kiện .net làm việc trên các khái niệm về Đại biểu (như nút Click)

Đại biểu được sử dụng khi bạn không biết mã để gọi vào thời gian chạy Vì vậy, tại thời điểm đó đại biểu là sử dụng để xử lý các sự kiện

http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx

0

một đại biểu chỉ là một cái gì đó mà một nhiệm vụ được giao. Mục đích chính của phái đoàn là tách mã và cho phép linh hoạt hơn và tái sử dụng.

Trong lập trình và lập trình hướng đối tượng cụ thể, điều này có nghĩa là khi một phương thức được gọi để thực hiện một số công việc, nó sẽ chuyển công việc vào phương thức của đối tượng khác có tham chiếu đến. Tham chiếu có thể trỏ đến bất kỳ đối tượng nào chúng ta muốn, miễn là đối tượng tuân theo một tập các phương thức được xác định trước. Chúng tôi gọi nó là "lập trình cho một giao diện" (so với lập trình cho một lớp thực hiện cụ thể). Một giao diện cơ bản là một khuôn mẫu chung và không có triển khai thực hiện; nó đơn giản có nghĩa là một công thức, một tập hợp các phương pháp, điều kiện tiên quyết và postconditions (quy tắc).

ví dụ đơn giản:

SomeInterface 
{ 
    public void doSomething(); 
} 


SomeImplementation implements SomeInterface 
{ 
    public void doSomething() 
    { 
     System.err.println("Was it good for you?"); 
    } 

} 


SomeCaller 
{ 
    public void doIt(SomeInterface someInterface) 
    { 
     someInterface.doSomething(); 
    } 
} 

Bây giờ bạn nhìn thấy tôi có thể sử dụng bất cứ thực hiện Tôi muốn bất cứ lúc nào mà không thay đổi mã trong SomeCaller vì loại đó doIt() được truyền không phải là bê tông nhưng khá trừu tượng vì nó là một giao diện . Trong thế giới Java, điều này thường được thể hiện trong mô hình dịch vụ nơi bạn gọi ra một dịch vụ (một đối tượng tự quảng cáo như một dịch vụ thông qua một giao diện cụ thể) và dịch vụ này sẽ gọi cho các đại biểu để giúp nó thực hiện công việc của mình. Các phương thức của dịch vụ được đặt tên là các nhiệm vụ thô (makePayment(), createNewUser(), vv), trong khi nội bộ nó làm rất nhiều nếu công việc nitty-gritty thông qua ủy nhiệm, với các loại của các đại biểu là giao diện thay vì triển khai cụ thể.

SomeService 
{ 
    SomeInterface someImplementation = ... // assign here 
    SomeOtherInterface someOtherImplementation = ... // okay, let's add a second 

    public void doSomeWork() 
    { 
     someImplementation.doSomething(); 
     someOtherImplementation.doSomethingElse(); 
    } 
} 

(N.B .: Bằng cách nào một thực hiện được giao nằm ngoài phạm vi của chủ đề này. Lookup đảo ngược tầm kiểm soát và dependency injection.)

2

Một đại biểu chỉ là một đối tượng có thể tham khảo một phương pháp. Vì vậy, khi chúng ta tạo một đại biểu, chúng ta đang tạo một đối tượng có thể giữ một tham chiếu đến một phương thức. Hơn nữa, phương pháp này có thể được gọi thông qua tham chiếu này. Vì vậy, một đại biểu có thể gọi phương thức mà nó đề cập đến. Lợi thế chính của một đại biểu là nó cho phép chúng ta chỉ định một cuộc gọi đến một phương thức, nhưng phương thức thực sự được gọi được xác định trong thời gian chạy, không phải lúc biên dịch.

Simple Đại biểu

Declaration of delegate: 
delegate-modifier delegate return-type delegate-name(parameters) 
Implementation of delegate: 
Delegate-name delegate-object=new Delegate-name(method of class) 

http://knowpacific.wordpress.com/2012/01/26/delegate/

2

Ở đây tôi sẽ giải thích các đại biểu, đại biểu multicast và sử dụng của họ .. đại biểu là một loại nắm giữ tài liệu tham khảo phương pháp (s) trong một vật. Nó cũng được gọi là một con trỏ hàm an toàn kiểu. Chúng ta có thể nói một delegate là một kiểu xác định chữ ký phương thức.

Khi bạn khởi tạo một đại biểu, bạn có thể kết hợp cá thể của nó với bất kỳ phương thức nào có chữ ký tương thích. Bạn có thể gọi (hoặc gọi) phương thức thông qua thể hiện ủy nhiệm. Các đại biểu được sử dụng để chuyển các phương thức làm đối số cho các phương thức khác. Trình xử lý sự kiện không có gì khác hơn các phương thức được gọi thông qua các đại biểu. Ưu điểm của việc sử dụng đại biểu là, Đóng gói cuộc gọi của phương thức từ người gọi Sử dụng hiệu quả đại biểu cải thiện hiệu suất của ứng dụng Được sử dụng để gọi phương thức không đồng bộ. Có một số tính chất của các đại biểu là

Delegates are like C++ function pointers but are type safe. 
Delegates allow methods to be passed as parameters. 
Delegates can be used to define callback methods. 
Delegates can be chained together; for example, multiple methods can be called on a single event. 
Methods do not have to match the delegate signature exactly. 

public delegate type_of_delegate delegate_name() // Tuyên bố

You can use delegates without parameters or with parameter list 
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String. 

Ví dụ sau đây cho thấy một hoạt động đại biểu:

namespace MyDelegate 
    { 
     class Program 
     { 
      private delegate void Show(string s); 


      // Create a method for a delegate. 
      public static void MyDelegateMethod(string me 

ssage) 
     { 
      System.Console.WriteLine(message); 
     } 

     static void Main(string[] args) 
     { 
      Show p = MyDelegateMethod; 
      p("My Delegate"); 
      p.Invoke("My Delegate"); 
      System.Console.ReadLine(); 
     } 
    } 
} 

Multicast là gì Đại biểu?

Đây là đại biểu chứa tham chiếu của nhiều phương pháp. Các đại biểu Multicast chỉ phải chứa các phương thức trả về void, nếu không có một ngoại lệ thời gian chạy.

delegate void MyMulticastDelegate(int i, string s); 
Class Class2 
{ 
    static void MyFirstDelegateMethod(int i, string s) 
    { 
    Console.WriteLine("My First Method"); 
    } 

    static void MySecondDelegateMethod(int i, string s) 
    { 
    Console.WriteLine("My Second Method"); 
    } 

    static void Main(string[] args) 
    { 
    MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod); 
    Method+= new MyMulticastDelegate (MySecondDelegateMethod); 
    Method(1,"Hi");    // Calling 2 Methodscalled 
    Method-= new MyMulticastDelegate (MyFirstDelegateMethod); 
    Method(2,"Hi");    //Only 2nd Method calling 
    } 
} 

Tại đây Đại biểu được thêm bằng toán tử + = và xóa bằng toán tử - =.

Loại đại biểu có nguồn gốc từ lớp Đại biểu trong Khuôn khổ .NET. Các loại đại biểu được niêm phong - chúng không thể được bắt nguồn. Do đại biểu được khởi tạo là một đối tượng, nó có thể được chuyển như một tham số hoặc được gán cho một thuộc tính. Điều này cho phép một phương thức để chấp nhận một đại biểu như một tham số, và gọi cho đại biểu vào một thời gian sau đó. Điều này được gọi là gọi lại không đồng bộ.

0

Đại biểu được sử dụng chủ yếu với các sự kiện.

Nhu cầu là:

Bạn không muốn thực hiện một đoạn mã vào thời điểm đó khi bạn chạy chương trình. Sau khi chạy chương trình bạn muốn thực thi đoạn mã đó bất cứ khi nào một sự kiện xảy ra.

Ví dụ:

  1. Ứng dụng Console - mã có thể được thực hiện chỉ tại thời điểm bạn chạy chương trình. (Được viết bên trong phương thức chính)
  2. Ứng dụng Windows (lập trình giao diện người dùng) - mã có thể được thực hiện khi nhấp vào nút sau khi chạy chương trình.

Đây là những gì họ nói, bạn không biết phương thức nào sẽ gọi vào lúc biên dịch. bạn biết nó chỉ trong thời gian chạy đó là khi nhấp vào nút.

Không có người được ủy quyền, không thể lập trình giao diện người dùng. Bởi vì bạn đang thực thi mã bất cứ khi nào người dùng thực hiện các sự kiện được nhấn nút, gõ vào textbox, chọn mục DropDownList và vân vân ....

1

Một đối tượng đại biểu là một đối tượng mà đối tượng khác tư vấn khi có điều gì xảy ra trong đối tượng đó. Đối với trường hợp , người sửa chữa của bạn là người được ủy quyền của bạn nếu có điều gì đó xảy ra với ô tô của bạn. bạn đi đến người sửa chữa của bạn và yêu cầu anh ta sửa chữa chiếc xe cho bạn (mặc dù một số người thích tự sửa chữa chiếc xe, trong trường hợp đó, họ là đại diện của họ cho chiếc xe của họ).

1

Đại biểu là đối tượng đại diện cho con trỏ đến hàm. Tuy nhiên, nó không phải là một con trỏ hàm thông thường ở chỗ nó:

1) là Object Oriented

2) là loại an toàn, tức là nó chỉ có thể điểm đến một phương pháp và bạn không thể đọc được địa chỉ bộ nhớ nguyên nó là chỉ đến

3) Được nhập mạnh mẽ. Nó chỉ có thể trỏ đến các phương thức phù hợp với chữ ký của nó.

4) Có thể trỏ đến nhiều phương thức cùng một lúc.

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