Tôi sử dụng đại biểu ở đâu? [đóng cửa]


109

Một số địa điểm trong thế giới thực kêu gọi đại biểu là gì? Tôi tò mò không biết những tình huống hoặc kiểu mẫu nào hiện diện mà phương pháp này là giải pháp tốt nhất. Không cần mã.

Câu trả lời:


33

Đại biểu là một kiểu được đặt tên xác định một kiểu phương thức cụ thể. Cũng giống như một định nghĩa lớp đưa ra tất cả các thành viên cho loại đối tượng nhất định mà nó định nghĩa, thì ủy viên sẽ đưa ra chữ ký phương thức cho loại phương thức mà nó định nghĩa.

Dựa trên câu lệnh này, một đại biểu là một con trỏ hàm và nó xác định hàm đó trông như thế nào.

Một ví dụ tuyệt vời cho ứng dụng đại biểu trong thế giới thực là Vị từ . Trong ví dụ từ liên kết, bạn sẽ nhận thấy rằng Array.Find nhận mảng để tìm kiếm và sau đó là một vị từ để xử lý các tiêu chí của những gì cần tìm. Trong trường hợp này, nó chuyển một phương thức ProductGT10 phù hợp với chữ ký Vị ngữ.


154

Như đã nêu trong "Học C # 3.0: Nắm vững các nguyên tắc cơ bản của C # 3.0"

Kịch bản chung: Khi một nguyên thủ quốc gia qua đời, Tổng thống Hoa Kỳ thường không có thời gian đích thân đến dự tang lễ. Thay vào đó, ông cử một đại biểu. Thường thì đại biểu này là Phó Tổng thống, nhưng đôi khi không có VP và Tổng thống phải cử người khác, chẳng hạn như Ngoại trưởng hoặc thậm chí Đệ nhất phu nhân. Anh ta không muốn “giao quyền” của mình cho một người duy nhất; anh ta có thể giao trách nhiệm này cho bất kỳ ai có thể thực hiện đúng giao thức quốc tế.

Tổng thống xác định trước trách nhiệm nào sẽ được giao (dự tang lễ), những thông số nào sẽ được thông qua (lời chia buồn, lời tử tế), và giá trị mà ông hy vọng nhận lại (thiện chí). Sau đó, ông chỉ định một người cụ thể cho trách nhiệm được ủy nhiệm đó vào "thời gian chạy" khi quá trình làm tổng thống của ông tiến triển.

Trong kịch bản lập trình: Bạn thường phải đối mặt với các tình huống mà bạn cần thực hiện một hành động cụ thể, nhưng bạn không biết trước phương thức nào, hoặc thậm chí đối tượng nào, bạn sẽ muốn gọi để thực hiện nó.

Ví dụ: Một nút có thể không biết đối tượng hoặc đối tượng nào cần được thông báo. Thay vì nối nút với một đối tượng cụ thể, bạn sẽ kết nối nút với một đại biểu và sau đó phân giải đại biểu đó thành một phương pháp cụ thể khi chương trình thực thi.


1
Tại sao không chỉ đơn giản sử dụng các hàm / lambdas ẩn danh?
Pacerier

5
@Pacerier Đây là một phản hồi muộn và bạn có thể đã khám phá ra câu trả lời, nhưng vì lợi ích của những người đọc khác, những người tìm thấy điều này: một hàm ẩn danh là một loại ủy quyền.
Anthony

10
@ Anthony + Pacerier: Một phương pháp vô danh KHÔNG phải là một đại biểu. Phương thức ẩn danh là một đoạn mã. Một đại biểu là một con trỏ trỏ đến đoạn mã đó. Bạn không thể có một phương thức ẩn danh mà không có một đại biểu trỏ đến nó, nếu không nó sẽ không bao giờ được gọi. Lambda là một toán tử, được sử dụng để xây dựng các biểu thức lambda. Các biểu thức Lambda chủ yếu dẫn đến các phương thức vô danh sẽ được trỏ tới bởi ... một đại biểu.
Martin Mulder

Tôi ngớ ngẩn, nhưng tôi sẽ chỉ tạo câu lệnh If ElseIf nếu tôi không biết cách sử dụng khi nút được nhấn. Tôi nói tôi ngớ ngẩn.
JustJohn

Phương thức ẩn danh @Pacerier được giới thiệu trong C # 2.0 và Lambda được giới thiệu trong C # 3.0 nếu Lambda giới thiệu trước, sẽ không bao giờ có phương thức ẩn danh và thậm chí là ủy quyền!
AminM

18

Một cách sử dụng phổ biến của đại biểu cho Danh sách chung là thông qua đại biểu Hành động (hoặc tương đương ẩn danh của nó) để tạo hoạt động foreach một dòng:

myList.Foreach( i => i.DoSomething());

Tôi cũng thấy đại biểu Predicate khá hữu ích trong việc tìm kiếm hoặc cắt bớt một Danh sách:

myList.FindAll( i => i.Name == "Bob");    
myList.RemoveAll( i => i.Name == "Bob");

Tôi biết bạn nói không cần mã, nhưng tôi thấy việc thể hiện tính hữu ích của nó qua mã dễ dàng hơn. :)


13

Sự kiện ràng buộc với Trình xử lý sự kiện thường là phần giới thiệu đầu tiên của bạn với các đại biểu ... Bạn thậm chí có thể không biết mình đang sử dụng chúng vì đại biểu được bao bọc trong lớp EventHandler.


5

Nếu bạn muốn xem cách mẫu Đại biểu được sử dụng trong mã thế giới thực, thì không cần tìm đâu xa hơn Cocoa trên Mac OS X. Cocoa là bộ công cụ giao diện người dùng ưa thích của Apple để lập trình trên Mac OS X và được mã hóa trong Objective C. Đó là được thiết kế để mỗi thành phần giao diện người dùng được thiết kế để mở rộng thông qua ủy quyền thay vì phân lớp con hoặc các phương tiện khác.

Để biết thêm thông tin, tôi khuyên bạn nên kiểm tra những gì Apple nói về các đại diện tại đây .


5

Tôi đã có một dự án sử dụng win32 Python.

Do nhiều lý do khác nhau, một số mô-đun đã sử dụng odbc.py để truy cập DB và các mô-đun khác - pyodbc.py.

Đã xảy ra sự cố khi một chức năng cần được sử dụng bởi cả hai loại mô-đun. Nó có một đối tượng kết nối được chuyển tới nó như một đối số, nhưng sau đó nó phải biết liệu sử dụng dbi.dbiDate hay datetime để biểu diễn thời gian.

Điều này là do odbc.py mong đợi, như các giá trị trong câu lệnh SQL, ngày là dbi.dbiDate trong khi pyodbc.py dự kiến ​​các giá trị datetime.

Một điều phức tạp nữa là các đối tượng kết nối được tạo bởi odbc.py và pyodbc.py không cho phép một đối tượng thiết lập các trường bổ sung.

Giải pháp của tôi là bọc các đối tượng kết nối được trả về bởi odbc.odbc (...) và pyodbc.pyodbc (...) bởi một lớp đại biểu, có chứa hàm biểu diễn thời gian mong muốn dưới dạng giá trị của một trường bổ sung và đại biểu nào tất cả các trường khác yêu cầu đối tượng kết nối ban đầu.


5

Tôi có cùng câu hỏi với bạn và đã truy cập trang web này để tìm câu trả lời.

Rõ ràng, tôi đã không hiểu nó tốt hơn mặc dù tôi đã đọc lướt qua các ví dụ trên chủ đề này.

Tôi đã tìm thấy một cách sử dụng tuyệt vời cho các đại biểu hiện tôi đã đọc: http://www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx

Điều này có vẻ rõ ràng hơn đối với người dùng mới vì Biểu mẫu phức tạp hơn nhiều so với các trang web ASP.NET có POST / GET (QueryString) ..

Về cơ bản, bạn xác định một đại biểu lấy "TextBox text " làm tham số.

// Hình thức 1

// Class Property Definition
public delegate void delPassData(TextBox text);


// Click Handler
private void btnSend_Click(object sender, System.EventArgs e)
{
     Form2 frm= new Form2();
     delPassData del=new delPassData(frm.funData);
     del(this.textBox1);
     frm.Show();
}

// TÓM TẮT: Định nghĩa ủy quyền, khởi tạo lớp Form2 mới, gán hàm funData () để ủy quyền, chuyển trong textBox của bạn cho ủy quyền. Hiển thị biểu mẫu.

// Form2

public void passData(TextBox txtForm1)
{

     label1.Text = txtForm1.Text;
}

// TÓM TẮT: Chỉ cần lấy TextBox txtForm1 làm tham số (như được định nghĩa trong đại diện của bạn) và gán văn bản nhãn cho văn bản của textBox.

Tôi hy vọng điều này khai sáng một số sử dụng trên các đại biểu :) ..


Phương thức lớp Form2 cần được đặt tên funData (thay vì passData) hoặc phép gán hàm Form1 cần được đặt tên là frm.passData (thay vì frm.funData).
ethan

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.