Tài liệu Tìm hiểu C# và ứng dụng của C# p 15 - Pdf 98

Delegate và Event Gvhd: Nguyễn Tấn Trần Minh Khang
87 Chương 12 Delegate và Event
Delegate có nghĩa là ủy quyền hay ủy thác. Trong lập trình đôi lúc ta gặp tình huống
phải thực thi một hành động nào đó, nhưng lại không biết sẽ gọi phương thức nào
của đối tượng nào. Chằng hạn, một nút nhấn button khi được nhấn phải thông báo
cho đối tượng nào đó biết, nhưng đối tượng này không thể được tiên đoán trong lúc
cài đặt lớp button. Vì vậy ta sẽ kết nối lớp button với một đối tượng ủy thác và ủy
thác (hay thông báo) cho đối tượng này trách nhiệm thực thi khi button được nhấn.
Đối tượng ủy thác sẽ được gán (đăng ký ủy thác) vào thời điểm khác thích hợp.
Event có nghĩa là sự kiện. Ngày nay mô hình lập trình giao diện người dùng đồ họa
(Graphical User Interface - GUI) đòi hỏi cách tiếp cận theo hướng sự kiện. Một ứng
dụng ngày nay hiển thị giao diện người dùng và chờ người dùng thao tác. Ứng với
mỗi thao tác như chọn một trình đơn, nhấn một nút button, nhập liệu vào ô textbox
… sẽ một sự kiện sẽ phát sinh. Một sự kiện có nghĩa là có điều gì đó đã xảy ra và
chương trình phải đáp trả.
Delegate và event là hai khái niệm có liên quan chặt chẽ với nhau. Bởi vì để quản lý
các sự kiện một cách mềm dẻo đòi hỏi các đáp trả phải được phân phối đến các
trình giải quyết sự kiện. Trình giải quyết sự kiện trong C# được cài đặt bằng
delegate.
Delegate còn được sử dụng như một hàm callback. Hàm callback là hàm có thể
được tự động gọi bởi hàm khác. Công dụng thứ hai này của delegate được đề cập
trong chương 19.
12.1 Delegate (ủy thác, ủy quyền)
Trong C#,
delegate
được hỗ trợ hoàn toàn bởi ngôn ngữ. Về mặt kỹ thuật,
delegate thuộc kiểu tham chiếu được dùng để đóng gói phương thức đã xác định
kiểu trả về và số lượng, kiểu tham số. Chúng ta có thể đóng gói bất kỳ phương thức

đó bằng cách khởi tạo với tham số là phương thức cho delegate.
12.1.1 Dùng delegate để xác định phương thức vào lúc chạy
Delegate được dùng để xác định (specify) loại (hay kiểu) của các phương thức dùng
để quản lý các sự kiện; hoặc để cài đặt các hàm callback trong ứng dụng. Chúng
cũng được dùng để xác định các phương thức tĩnh và không tĩnh (còn gọi là phương
thức thề hiện - instance methods: là phương chỉ gọi được thông qua một thể hiện
của lớp) chưa biết trước vào lúc thiết kế (có nghĩa là chỉ biết vào lúc chạy).
Ví dụ, giả sử chúng ta muốn tạo một lớp túi chứa đơn giản có tên là
Pair
(một
cặp). Lớp này chứa 2 đối tượng được sắp xếp. Chúng ta không biết trước được đối
tượng nào sẽ được truyền vào cho một thể hiện của lớp
Pair
, vì vậy không thể xây
dựng hàm sắp xếp tốt cho tất cả các trường hợp. Tuy nhiên ta sẽ đẩy trách nhiệm
này cho đối tượng bằng cách tạo phương thức mà công việc sắp xếp có thể ủy thác.
Nhờ đó ta có thể sắp thứ thự của các đối tượng chưa biết bằng cách ủy thác trách
nhiệm này chính phương thức của chúng.
Ta định nghĩa một
delegate
có tên
WhichIsFirst
trong lớp
Pair
. Phương thức
sort
sẽ nhận một tham số kiểu
WhichIsFirst
. Khi lớp
Pair

sắp xếp đối tượng
Dog

Student
. Sau đây là các bước thực hiện:
public class Pair
{
// cặp đối tượng
public Pair(object firstObject, object secondObject)
{
thePair[0] = firstObject;
thePair[1] = secondObject;
}
// biến lưu giữ hai đối tượng
private object[]thePair = new object[2];
Kế tiếp, ta override hàm
ToString()

public override string ToString( )
{
return thePair[0].ToString() + ", " + thePair[1].ToString();
Delegate và Event Gvhd: Nguyễn Tấn Trần Minh Khang
89
}
Chúng ta đã có hai đối tượng trong lớp
Pair
và có thể in chúng ra. Bây giờ là phần
sắp xếp chúng và in kết quả sắp xếp. Chúng ta không thể biết trước sẽ có loại đối
tượng nào, và vì vậy chúng ta sẽ ủy thác quyền quyết định đối tượng nào có thứ tự
trước cho chính các đối tượng. Như vậy ta sẽ yêu cầu đối tượng được xếp thứ tự

Bây giờ ta định nghĩa phương thức
Sort
của lớp
Pair

public void Sort(WhichIsFirst theDelegatedFunc)
{
if ( theDelegatedFunc(thePair[0],thePair[1]) ==
comparison.theSecondComesFirst )
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}
Phương thức này nhận một tham số
delegate
tên
WhichIsFirst
. Phương thức
Sort ủy thác quyền quyết định đối tượng nào có thứ tự trước cho phương thức
được đóng gói trong
delegate
. Trong thân hàm
Sort()
, có lời gọi phương thức
được ủy thác và xác định giá trị trả về.
Nếu trị trả về là
theSecondComesFirst
, hai đối tượng trong

Student

Dog
.
Gán tên cho
Student
lúc khởi tạo
public class Student
{
public Student(string name)
{
this.name = name;
}
Lớp
Student
yêu cầu hai phương thức, một
override
từ hàm
ToString()

một để đóng gói như phương thức được ủy thác.
Student
phải
override
hàm
ToString()
để phương thức
ToString()
trong
lớp

public Dog(int weight)
{
this.weight=weight;
}
// dogs are ordered by weight
Delegate và Event Gvhd: Nguyễn Tấn Trần Minh Khang
91
public static comparison WhichDogComesFirst( Object o1,
Object o2 )
{
Dog d1 = (Dog) o1;
Dog d2 = (Dog) o2;
return d1.weight > d2.weight ? theSecondComesFirst :
theFirstComesFirst;
}
public override string ToString( )
{
return weight.ToString( );
}
private int weight;
}
Chú ý rằng lớp
Dog
cũng override phương thức
ToString()
và cài đặt phương
thức tĩnh với nguyên mẫu hàm được khai báo trong
delegate
. Cũng chú rằng hai
phương thức chuẩn bị ủy thác của hai lớp

// theo thứ tự do chính chúng qui định.
public void Sort(WhichIsFirst theDelegatedFunc)
{
if ( theDelegatedFunc(thePair[0],thePair[1]) ==
comparison.theSecondComesFirst )
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}
Delegate và Event Gvhd: Nguyễn Tấn Trần Minh Khang
92

// phương thức sắp thứ tự ngược (giảm) các đối tượng
// theo thứ tự do chính chúng qui định.
public void ReverseSort( WhichIsFirst theDelegatedFunc)
{
if (theDelegatedFunc(thePair[0],thePair[1]) ==
comparison.theFirstComesFirst )
{
object temp = thePair[0];
thePair[0] = thePair[1];
thePair[1] = temp;
}
}
// kết hợp hai hàm ToString() của hai đối tượng
public override string ToString( )
{
return thePair[0].ToString( ) + ", " +

{
this.name = name;
}
// sinh viên sắp theo thứ tự tên
public static comparison WhichStudentComesFirst( object o1,
object o2 )
{
Student s1 = (Student) o1;
Student s2 = (Student) o2;
return (String.Compare(s1.name, s2.name) < 0 ?
comparison.theFirstComesFirst :
Delegate và Event Gvhd: Nguyễn Tấn Trần Minh Khang
93
comparison.theSecondComesFirst);
}
public override string ToString( )
{
return name;
}
private string name;
}
public class Test
{
public static void Main( )
{
// tạo hai đối tượng sinh viên và hai đối tượng chó
// đẩy chúng vào 2 đối tượng Pair
Student Jesse = new Student("Jesse");
Student Stacey = new Student ("Stacey");


Kết quả:
studentPair : Jesse, Stacey
dogPair : 65, 12
After Sort studentPair : Jesse, Stacey
After ReverseSort studentPair : Stacey, Jesse
After Sort dogPair : 12, 65
After ReverseSort dogPair : 65, 12
Delegate và Event Gvhd: Nguyễn Tấn Trần Minh Khang
94
Chương trình test tạo ra hai đối tượng Student và hai đối tượng Dog, sau đó đưa
chúng vào túi chứa
Pair
. Hàm khởi tạo của
Student
nhận vào tên sinh viên cò
hàm khởi tạo
Dog
nhận vào trọng lượng của chó.
Student Jesse = new Student("Jesse");
Student Stacey = new Student ("Stacey");
Dog Milo = new Dog(65);
Dog Fred = new Dog(12);
Pair studentPair = new Pair(Jesse,Stacey);
Pair dogPair = new Pair(Milo, Fred);
Console.WriteLine("studentPair\t\t\t:{0}",studentPair.ToString());
Console.WriteLine("dogPair\t\t\t\t: {0}", dogPair.ToString( ));
Sau đó in nội dung của hai túi chứa
Pair
để xem thứ tự của chúng. Kết quả như
sau:

Pair
, và sau đó là
phương thức
ReverseSort
. Kết quả được in trên màn hình
Console
như sau.
After Sort studentPair : Jesse, Stacey
After ReverseSort studentPair : Stacey, Jesse
After Sort dogPair : 12, 65
After ReverseSort dogPair : 65, 12


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status