C # biết hai thuật ngữ, delegate
và event
. Hãy bắt đầu với cái đầu tiên.
Đại biểu
A delegate
là một tham chiếu đến một phương thức. Giống như bạn có thể tạo một tham chiếu đến một thể hiện:
MyClass instance = myFactory.GetInstance();
Bạn có thể sử dụng một đại biểu để tạo một tham chiếu đến một phương thức:
Action myMethod = myFactory.GetInstance;
Bây giờ bạn có tham chiếu này đến một phương thức, bạn có thể gọi phương thức đó qua tham chiếu:
MyClass instance = myMethod();
Nhưng tại sao bạn? Bạn cũng có thể chỉ cần gọimyFactory.GetInstance()
trực tiếp. Trong trường hợp này bạn có thể. Tuy nhiên, có nhiều trường hợp để suy nghĩ về nơi bạn không muốn phần còn lại của ứng dụng có kiến thức về myFactory
hoặc gọimyFactory.GetInstance()
trực tiếp.
Một điều hiển nhiên là nếu bạn muốn có thể thay thế myFactory.GetInstance()
vàomyOfflineFakeFactory.GetInstance()
từ một vị trí trung tâm (hay còn gọi là factory method ).
Mô hình phương pháp nhà máy
Vì vậy, nếu bạn có một TheOtherClass
lớp và nó cần sử dụng myFactory.GetInstance()
, đây là cách mã sẽ trông như thế nào khi không có đại biểu (bạn sẽ cần phải TheOtherClass
biết về loại của bạn myFactory
):
TheOtherClass toc;
//...
toc.SetFactory(myFactory);
class TheOtherClass
{
public void SetFactory(MyFactory factory)
{
// set here
}
}
Nếu bạn sử dụng đại biểu, bạn không phải để lộ loại nhà máy của tôi:
TheOtherClass toc;
//...
Action factoryMethod = myFactory.GetInstance;
toc.SetFactoryMethod(factoryMethod);
class TheOtherClass
{
public void SetFactoryMethod(Action factoryMethod)
{
// set here
}
}
Vì vậy, bạn có thể cho một đại biểu cho một số lớp khác để sử dụng, mà không để lộ loại của bạn cho họ. Điều duy nhất bạn phơi bày là chữ ký của phương thức của bạn (bạn có bao nhiêu tham số và như vậy).
"Chữ ký của phương pháp của tôi", trước đây tôi đã nghe điều đó ở đâu? Ồ vâng, giao diện !!! giao diện mô tả chữ ký của cả một lớp. Hãy nghĩ về các đại biểu như mô tả chữ ký của chỉ một phương pháp!
Một điểm khác biệt lớn giữa giao diện và đại biểu là khi bạn viết lớp, bạn không cần phải nói với C # "phương thức này thực hiện kiểu đại biểu đó". Với các giao diện, bạn cần phải nói "lớp này thực hiện kiểu giao diện đó".
Hơn nữa, một tham chiếu đại biểu có thể (với một số hạn chế, xem bên dưới) tham chiếu nhiều phương thức (được gọi là MulticastDelegate
). Điều này có nghĩa là khi bạn gọi đại biểu, nhiều phương thức được đính kèm rõ ràng sẽ được thực thi. Một tham chiếu đối tượng luôn có thể chỉ tham chiếu đến một đối tượng.
Các hạn chế đối với a MulticastDelegate
là chữ ký (phương thức / ủy nhiệm) không được có bất kỳ giá trị trả về ( void
) nào và các từ khóa out
và ref
không được sử dụng trong chữ ký. Rõ ràng, bạn không thể gọi hai phương thức trả về một số và mong đợi chúng trả về cùng một số. Khi chữ ký tuân thủ, đại biểu sẽ tự động a MulticastDelegate
.
Biến cố
Các sự kiện chỉ là các thuộc tính (như get; set; thuộc tính cho các trường đối tượng) hiển thị đăng ký cho đại biểu từ các đối tượng khác. Tuy nhiên, các thuộc tính này không hỗ trợ get; set;. Thay vào đó, họ hỗ trợ thêm; tẩy;
Vì vậy, bạn có thể có:
Action myField;
public event Action MyProperty
{
add { myField += value; }
remove { myField -= value; }
}
Sử dụng trong UI (WinForms, WPF, UWP, v.v.)
Vì vậy, bây giờ chúng ta biết rằng một đại biểu là một tham chiếu đến một phương thức và chúng ta có thể có một sự kiện để cho thế giới biết rằng họ có thể cung cấp cho chúng ta các phương thức của họ để được tham chiếu từ đại biểu của chúng ta và sau đó chúng ta là một nút UI có thể hỏi bất cứ ai quan tâm đến việc tôi đã được nhấp hay không, để đăng ký phương thức của họ với chúng tôi (thông qua sự kiện chúng tôi tiếp xúc). Chúng tôi có thể sử dụng tất cả các phương pháp đã được trao cho chúng tôi và tham chiếu chúng bởi đại biểu của chúng tôi. Và sau đó, chúng tôi sẽ chờ và đợi .... cho đến khi một người dùng đến và nhấp vào nút đó, thì chúng tôi sẽ có đủ lý do để triệu tập đại biểu. Và bởi vì đại biểu tham chiếu tất cả các phương thức được cung cấp cho chúng tôi, tất cả các phương thức đó sẽ được gọi. Chúng ta không biết những phương thức đó làm gì, chúng ta cũng không biết lớp nào thực hiện các phương thức đó. Tất cả những gì chúng tôi quan tâm là ai đó quan tâm đến việc chúng tôi được nhấp vào,
Java
Các ngôn ngữ như Java không có đại biểu. Họ sử dụng giao diện thay thế. Cách họ làm là yêu cầu bất kỳ ai quan tâm đến 'chúng tôi được nhấp', để thực hiện một giao diện nhất định (với một phương thức nhất định mà chúng tôi có thể gọi), sau đó cung cấp cho chúng tôi toàn bộ ví dụ thực hiện giao diện. Chúng tôi giữ một danh sách tất cả các đối tượng thực hiện giao diện này và có thể gọi 'phương thức nhất định mà chúng tôi có thể gọi' bất cứ khi nào chúng tôi được nhấp.