Kiểu delegate Kiểu delegate là 1 kiểu chứa tham chiếu đến 1 hoặc nhiều phương thức, đó có thể là phương thức của class hoặc phương thức của đối tượng.. Delegate gần giống với con trỏ hà
Trang 1Delegates, Events and Lambda Expressions
Ủy quyền, Sự kiện và biểu thức Lambda
Trang 2Kiểu delegate
Kiểu delegate là 1 kiểu chứa tham chiếu đến 1 hoặc nhiều phương thức, đó có thể là phương thức của class hoặc phương thức của đối tượng Delegate gần giống với con trỏ hàm trong C/C++
Kiểu delegate thực chất là 1 class kế thừa từ class System.MulticastDelegate
Delegate cho phép truyền một hàm dưới dạng tham số của hàm khác
Trang 3Định nghĩa
kiểu delegate
Định nghĩa kiểu delegate bằng cách dùng từ khóa delegate đi với kiểu dữ liệu trả về, tên kiểu delegate, danh sách tham số
public delegate double Function(double x)
Để một delegate tham chiếu được đến một phương thức thì cả delegate phải có chung nguyên mẫu (tức là chung kiểu trả về và danh sách tham số)
Trang 4public static int Subtract( int x, int y) { return x – y; }
static void Main( string [] args) {
Trang 5 GetInvocationList() (Delegate[]): trả về 1 mảng chứa các phương thức hiện có trong đối tượng delegate
Remove hàm tĩnh, trả về 1 delegate sau khi xóa 1 phương thứcpublic static Delegate Remove(Delegate source,
Delegate value)
Trang 616 kiểu, tối thiểu là 0 Nguyên mẫu delegate:
delegate void Action<T1, T2, …>(T1 obj1, T2 obj2,
…)
Dạng tổng quát của Func<T> là Func<T1, T2, …, TResult>, tương
tự như Action<T> nhưng có thêm kiểu dữ liệu trả về ở cuối cùngdelegate TResult Func<T1, T2, …, TResult>(T1 obj1, T2 obj2, …)
Trang 7Gửi thông báo
thay đổi trạng
thái của
đối tượng
bằng delegate
Ý tưởng: Mỗi khi đối tượng thay đổi trạng thái, ta sẽ gọi hàm xử lí
sự thay đổi trạng thái đó Hàm này sẽ được truyền vào đối tượng thông qua 1 đối tượng delegate
Ví dụ sau đây sẽ viết về 1 đối tượng xe, mỗi khi xe thay đổi vận tốc,
nó sẽ thông báo về vận tốc hiện tại của nó
Trang 8Gửi thông báo
public int VanToc {
get { return vantoc; } set
{ vantoc = value ;
if (thaydoi != null ) thaydoi( String Format( "Van toc hien tai la {0} km/h" , vantoc)); }
} private Action < string > thaydoi;
public void TruyenHamXuLi( Action < string > ham) {
thaydoi = ham;
} }
Trang 9Gửi thông báo
Car a = new Car();
a.TruyenHamXuLi(Console.WriteLine); for (int i = 0; i < 5; i++)
{ a.VanToc = 10 * i;
}}
Trang 10public static void Subtract( int x, int y) { Console WriteLine(x - y); }
static void Main( string [] args) {
Trang 11Multicast
delegates
Bằng các sử dụng multicast delegate, ta có thể thêm hoặc xóa các hàm xử lí khi xe thay đổi vận tốc Ở class Car bên trên, ta thay hàm TruyenHamXuLi bằng 2 hàm thêm và xóa như ở dưới
public void ThemHamXuLi( Action < string > ham) {
Trang 12Multicast
delegates
static void Main( string [] args) {
Car a = new Car ();
a.ThemHamXuLi( Console WriteLine); for ( int i = 0; i < 3; i++)
{ a.VanToc = 10 * i;
} a.XoaHamXuLi( Console WriteLine); for ( int i = 3; i < 5; i++)
{ a.VanToc = 10 * i;
} }
Trang 13 Event là cách mà 1 class có thể đưa ra các thông báo cho các class khác khi có 1 sự kiện nào đó xảy ra với nó Ví dụ như thông báo thay đổi vận tốc của đối tượng Car như bên trên
Ta có thể tạo 1 sự kiện như ví dụ bên trên bằng cách tạo 1 đối tượng delegate có mức truy cập private và tạo các hàm để thêm
và bớt các phương thức xử lí
Với từ khóa event, ta có thể rút ngắn quá trình khai báo 1 event chỉ trong 1 dòng
Trang 14class Car
{ private int vantoc;
public int VanToc {
get { return vantoc; } set
{ vantoc = value ;
if (ThayDoi != null ) ThayDoi( String Format( "Van toc hien tai la {0} km/h" , vantoc));
} } public event Action < string > ThayDoi;
}
Trang 15static void Main( string [] args) {
Car a = new Car ();
a.ThayDoi += Console WriteLine; for ( int i = 0; i < 3; i++)
{ a.VanToc = 10 * i;
} }
Kết quả:
Van toc hien tai la 0 km/h Van toc hien tai la 10 km/h Van toc hien tai la 20 km/h
Trang 16 Delegate này không trả về giá trị nào, có 2 đối số:
sender: đối tượng tạo ra event
e: đối tượng mô tả các thông tin về event
Ta có thể tạo ra class dẫn xuất từ class EventArgs để chứa thông tin về event
Trang 17Custom Event
Argument
class CarEventArgs
{ public readonly string msg;
public CarEventArgs(string message) {
msg = message;
}}
Trang 18Custom Event
Argument
class Car {
private int vantoc;
public int VanToc {
get { return vantoc; } set
{ vantoc = value ;
if (ThayDoi != null ) ThayDoi( this , new CarEventArgs (String.Format( "Van toc hien tai la {0} km/h" , vantoc)));
} } public delegate void CarEventHandler( object sender, CarEventArgs e);
public event CarEventHandler ThayDoi;
}
Trang 19static void a_ThayDoi( object sender, CarEventArgs e) {
Console WriteLine(e.msg);
}
Trang 20 Cho phép ta không cần phải tạo ra các delegate mới cho các event
Trang 21public event CarEventHandler ThayDoi;
Ta có thể viết gọn lại như sau:
public event EventHandler<CarEventArgs> ThayDoi;
Trang 23{ Console.WriteLine("Xe thay doi van toc");
Console.WriteLine(e.msg);
};