Các Chủ Đề Tiến Bộ Trong C# part 3 - Pdf 68


Delegate
Delegate có thể được xem như là kiểu đối tượng mới trong C#, mà có môt số điểm quen
thuộc với lớp.chúng tồn tại trong tình huống mà ta muốn truyền phương thức xung quanh
những phương thức khác.để minh hoạ ta xem dòng mã sau:
int i = int.Parse("99");
Chúng ta quen với việc truyền dữ liệu đến một phương thức như là thông số,vì vậy ý
tường truyền phương thức như là thông số nghe có vẻ hơi lạ đối với chúng ta.tuy nhiên có
trường hợp mà ta có 1 phương thức mà làm 1 điều gì đó, nhiều hơn là xử lí dữ liệu,
phương thức đó có thể cần làm điều gì đó mà liên quan đến việc thực thi phương thức
khác.phức tạp hơn, bạn không biết vào lúc nào thì phương thức thứ hai sẽ được biên dịch.
thông tin đó chỉ biết vào lúc chạy , và chính vì lí do đó mà phương thức 2 sẽ cần truyền
vào như là thông số cho phương thức đầu tiên.điều này nghe có vẻ hơi khó hiểu,nhưng nó
sẽ được làm rõ hơn trong 1 vài ví dụ sau:
Luồng bắt đầu: C# có thể bảo máy tính bắt đầu một chuỗi thực thi mới song song vớ
i
việc thực thi đương thời.1 chuỗi liên tiếp này gọi là luồng,và việc bắt đầu này được làm
bằng cách dùng phương thức, Start() trên 1 thể hiện của lớp cơ
sở.System.Threading.Thread. ( chi tiết hơn về luồng ở chương 5).khi chương trình bắt
đầu chạy,nơi nó bắt đầu là main(). tương tự như vậy khi bạn muốn máy tính chạy một
chuỗi thực thi thì bạn phải báo cho máy tính biết bắt
đầu chạy là ở đâu. bạn phải cung cấp
cho nó chi tiết của phương thức mà việc thực thi có thể bắt đầu.-nói cách khác , phương
thức Thread.Start() phải lấy 1 thông số mà định nghĩa phương thức được thi hành bởi
luồng.
Lớp thư viện chung . khi 1 nhiệm vụ chứa đựng nhiệm vụ con mà mã của các nhiệm vụ
con này được viết trong các thư viện chỉ có sử dụng thư
viện mới biết nó làm gì.ví dụ ,
chúng ta muốn viết một lớp chứa một mảng đối tuợng và sắp nó tăng dần. 1 phần công
việc được lặp lại là lấy 2 đối tượng trong lớp so sánh với nhau để xem đối tượng nào
đứng truớc.nếu ta muốn lớp có khả năng sắp xếp bất kì đối tượng nào, không có cách nào

Đầu tiên ta phải đị
nh nghĩa delegate mà ta muốn dùng ,nghĩa là bảo cho trình biên dịch
biết loại phương thức mà delegate sẽ trình bày.sau đó ta tạo ra các thể hiện của delegate.
Cú pháp
delegate void VoidOperation(uint x);
Ta chỉ định mỗi thể hiện của delegate có thể giữ một tham chiếu đến 1 phương thức mà
chứa một thông số uint và trả vầ kiểu void.
Ví dụ khác : nếu bạn muốn định nghĩa 1 delegate gọi là twolongsOp mà trình bày 1 hàm
có 2 thông số kiểu long và trả về kiểu double. ta có thể viết :
delegate double TwoLongsOp(long first, long second);
Hay 1 delegate trình bày phương thức không nhận thông số và trả về kiểu string
delegate string GetAString();
Cú pháp cũng giống như phương thức , ngoại trừ việc không có phần thân của phương
thức,và bắt đầu với delegate.ta cũng có thể áp dụng các cách thức truy nhập thông thường
trên một định nghĩa delegate - public,private,protected ...
public delegate string GetAString();
Mỗi lần ta định nghĩa một delegate chúng ta có thể tạo ra một thể hiện của nó mà ta có
thể dùng đề lưu trữ các chi tiết của 1 phưong thức cụ thể.
Lưu ý : với lớp ta có 2 thuật ngữ riêng biệt : lớp để chỉ định nghĩa chung , đối tượng để
chỉ một thể hiện của 1 lớp, tuy nhiên đối với delegate ta chỉ có một thuật ngữ là '1
delegate' khi tạ
o ra một thể hiện của delegate ta cũng gọi nó là delegate. vì vậy cần xem
xét ngữ cảnh để phân biệt.
Đoạn mã sau minh hoạ cho 1 delegate:
private delegate string GetAString();

static void Main(string[] args)
{
int x = 40;
GetAString firstStringMethod = new GetAString(x.ToString);

{
int x = 40;
GetAString firstStringMethod = new GetAString(x.ToString);
Console.WriteLine("String is " + firstStringMethod());
Currency balance = new Currency(34, 50);
firstStringMethod = new GetAString(balance.ToString);
Console.WriteLine("String is " + firstStringMethod());
firstStringMethod = new GetAString(Currency.GetCurrencyUnit);
Console.WriteLine("String is " + firstStringMethod());
Đoạn mã này chỉ cho ta biết làm thế nào để gọi 1 phương thức qua trung gian là
delegate,đăng kí lại delegate để tham chiếu đến một phương thức khác trên 1 thể hiện
khác của lớp.
Tuy nhiên ta vẫn chưa nắm rõ được quy trình truyền 1 delegate đến 1 phương thức khác,
cũng như chưa thấy được lợi ích của delegate qua ví dụ trên. như ta có thể gọi trực tiếp
ToString() từ int hay currency mà không cần delegate.ta cần những ví dụ ph
ức tạp hơn để
hiểu rõ delegate. ta sẽ trình bày 2 ví dụ : ví dụ 1 đơn giản sử dụng delegate để gọi vào
thao tác khác..nó chỉ rõ làm thế nào để truyền delegate đến phương thức và cách sử dụng
mảng trong delegate . ví dụ 2 phức tạp hơn là lớp BubbleSorter, mà thực thi 1 phương
thức sắp xếp mảng đối tượng tăng dần. lớp này sẽ rất khó viết nếu không có delegate.
Ví dụ SimpleDelegate

Trong ví dụ này ta sẽ tạo lớp MathOperations mà có vài phương thức static để thực thi 2
thao tác trên kiểu double, sau đó ta dùng delegate để gọi những phương thức này.lớp như
sau:
class MathsOperations
{
public static double MultiplyByTwo(double value)
{
return value*2;

ProcessAndDisplayNumber(operations[i], 7.94);
ProcessAndDisplayNumber(operations[i], 1.414);
Console.WriteLine();
}
}

static void ProcessAndDisplayNumber(DoubleOp action, double value)
{
double result = action(value);
Console.WriteLine(
"Value is {0}, result of operation is {1}", value, result);
} Trong đoạn mã này ta khởi tạo 1 mảng delegate doubleOp.mỗi phần tử của mảng được
khởi động để tham chiếu đến 1 thao tác khác được thực thi bởi lớp MathOperations.sau
đó , nó lặp xuyên suốt mảng,ứng dụng mỗi thao tác đến 3 kiểu giá trị khác nhau.điều này
minh họa cách sử dụng delegate- là có thể nhóm những phương thức lại với nhau thành
mảng để sử dụng, để ta có thể g
ọi một vài phương thức trong vòng lặp.
Chỗ quan trọng trong đoạn mã là chỗ ta truyền 1 delegate vào phương thức
ProcessAndDisplayNumber(), ví dụ:

ProcessAndDisplayNumber(operations[i], 2.0);
Ở đây ta truyền tên của delegate,nhưng không có thông số nào.cho rằng operation[i] là 1
delegate :
operation[i] nghĩa là 'delegate',nói cách khác là phương thức đại diện cho delegate
operation[i](2.0) nghĩa là ' gọi thực sự phương thức này, truyền giá trị vào trong ngoặc'.
Phương thức ProcessAndDisplayNumber() được định nghĩa để lấy 1 delegate như là
thông số đầu tiên của nó :


Nhờ tải bản gốc
Music ♫

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