Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 11 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
11
Dung lượng
173,68 KB
Nội dung
Delegate Delegate xem kiểu đối tượng C#, mà có mơt số điểm quen thuộc với lớp.chúng tồn tình mà ta muốn truyền phương thức xung quanh 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 liệu đến phương thức thơng số,vì ý tường truyền phương thức thơng số nghe lạ chúng ta.tuy nhiên có trường hợp mà ta có phương thức mà làm điều đó, nhiều xử lí liệu, phương thức cần làm điều 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 phương thức thứ hai biên dịch thơng tin biết vào lúc chạy , lí mà phương thức cần truyền vào thông số cho phương thức đầu tiên.điều nghe khó hiểu,nhưng làm rõ vài ví dụ sau: Luồng bắt đầu: C# bảo máy tính bắt đầu chuỗi thực thi song song với việc thực thi đương thời.1 chuỗi liên tiếp gọi luồng,và việc bắt đầu làm cách dùng phương thức, Start() thể lớp sở.System.Threading.Thread ( chi tiết luồng chương 5).khi chương trình bắt đầu chạy,nơi bắt đầu main() tương tự bạn muốn máy tính chạy chuỗi thực thi bạn phải báo cho máy tính biết bắt đầu chạy đâu bạn phải cung cấp cho chi tiết phương thức mà việc thực thi bắt đầu.-nói cách khác , phương thức Thread.Start() phải lấy thông số mà định nghĩa phương thức thi hành luồng Lớp thư viện chung nhiệm vụ chứa đựng nhiệm vụ mà mã nhiệm vụ viết thư viện có sử dụng thư viện biết làm gì.ví dụ , muốn viết lớp chứa mảng đối tuợng tăng dần phần công việc lặp lại lấy đối tượng lớp so sánh với để xem đối tượng đứng truớc.nếu ta muốn lớp có khả xếp đối tượng nào, khơng có cách làm việc so sánh mã client dùng mảng đối tượng ta bảo cho ta biết cách so sánh cụ thể đối tượng mà muốn xếp.nói cách khác , mã client phải truyền cho lớp ta phương thức thích hợp mà gọi, để làm việc so sánh Nguyên tắc chung là: mã ta cần thông báo cho thời gian chạy NET biết phương thức xử lí tình Vì phải thiết lập nguyên tắc mà đôi lúc , phương thức cần lấy chi tiết phương thức khác thông số.kế tiếp minh họa cách làm điều đó.cách đơn giản truyền tên phương thức thông số.giả sử muốn bắt đầu luồng mới, có phương thức gọi entrypoint(), mà ta muốn luồng bắt đầu chạy từ đó: void EntryPoint() { // làm luồng cần làm } Có thể bắt đầu luồng với đoạn mã : Thread NewThread = new Thread(); Thread.Start(EntryPoint); // sai Thật cách đơn giản vài ngôn ngữ dùng cách c c++ ( c c++ thông số entrypoint trỏ hàm) Không may, cách thực thi trực tiếp gây số vấn đề an toàn kiểu.nhớ ta lập trình hướng đơí tượng, phương thức tồn độc lập , mà thường phải kết hợp với phương thức khác trưóc gọi.vì NET khơng cho làm điều này.thay vào ta muốn truyền phương thức ta phải gói chi tiết phương thức loại đối tượng delegate delegate đơn giản kiểu đối tượng đặc biệt- đặc biệt chổ ,trong tất đối tượng định nghĩa trước chứa đựng liệu , delegate chứa đựng chi tiết phương thức Dùng delegate C# Đầu tiên ta phải định nghĩa delegate mà ta muốn dùng ,nghĩa bảo cho trình biên dịch biết loại phương thức mà delegate trình bày.sau ta tạo thể delegate Cú pháp delegate void VoidOperation(uint x); Ta định thể delegate giữ tham chiếu đến phương thức mà chứa thông số uint trả vầ kiểu void Ví dụ khác : bạn muốn định nghĩa delegate gọi twolongsOp mà trình bày hàm có thông số kiểu long trả kiểu double ta viết : delegate double TwoLongsOp(long first, long second); Hay delegate trình bày phương thức khơng nhận thông số trả kiểu string delegate string GetAString(); Cú pháp giống phương thức , ngoại trừ việc khơng có phần thân phương thức,và bắt đầu với delegate.ta áp dụng cách thức truy nhập thông thường định nghĩa delegate - public,private,protected public delegate string GetAString(); Mỗi lần ta định nghĩa delegate tạo thể mà ta dùng đề lưu trữ chi tiết phưong thức cụ thể Lưu ý : với lớp ta có thuật ngữ riêng biệt : lớp để định nghĩa chung , đối tượng để thể lớp, nhiên delegate ta có thuật ngữ '1 delegate' tạo thể delegate ta gọi delegate cần xem xét ngữ cảnh để phân biệt Đoạn mã sau minh hoạ cho delegate: private delegate string GetAString(); static void Main(string[] args) { int x = 40; GetAString firstStringMethod = new GetAString(x.ToString); Console.WriteLine("String is" + firstStringMethod()); // With firstStringMethod initialized to x.ToString(), // the above statement is equivalent to saying // Console.WriteLine("String is" + x.ToString()); } Trong mã , ta tạo delegate GetAString, khởi tạo để tham khảo đến phương thức ToString() biến nguyên x biên dịch lỗi cố gắng khởi tạo FirstStringMethod với phương thức có thơng số vào kiểu trả chuỗi đặc tính delegate an toàn- kiểu ( type-safe) để thấy chúng phải đảm bảo dấu ấn ( signature) phương thức gọi đúng.tuy nhiên điều thú vị là, chúng không quan tâm kiểu đối tượng phương thức gọi chí liệu phương thức static phưong thức thể Để thấy điều ta mở rộng đoạn mã trên, dùng delegate FirstStringMethod để gọi phương thức khác đối tượng khác - phương thức thể phương thức tĩnh ta dùng lại cấu trúc currency, cấu trúc currency có overload riêng cho phương thức ToString().để xem xét delegate với phương thức tĩnh ta thêm phương thức tĩnh với dấu ấn currency: struct Currency { public static string GetCurrencyUnit() { return "Dollar"; } Bây ta sử dụng thể GetAString sau: private delegate string GetAString(); static void Main(string[] args) { 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ã cho ta biết làm để gọi phương thức qua trung gian delegate,đăng kí lại delegate để tham chiếu đến phương thức khác thể khác lớp Tuy nhiên ta chưa nắm rõ quy trình truyền delegate đến phương thức khác, chưa thấy lợi ích delegate qua ví dụ ta gọi trực tiếp ToString() từ int hay currency mà khơng cần delegate.ta cần ví dụ phức tạp để hiểu rõ delegate ta trình bày ví dụ : ví dụ đơn giản sử dụng delegate để gọi vào thao tác khác rõ làm để truyền delegate đến phương thức cách sử dụng mảng delegate ví dụ phức tạp lớp BubbleSorter, mà thực thi phương thức xếp mảng đối tượng tăng dần lớp khó viết khơng có delegate Ví dụ SimpleDelegate Trong ví dụ ta tạo lớp MathOperations mà có vài phương thức static để thực thi thao tác kiểu double, sau ta dùng delegate để gọi phương thức này.lớp sau: class MathsOperations { public static double MultiplyByTwo(double value) { return value*2; } public static double Square(double value) { return value*value; } } Sau ta gọi phương thức sau: using System; namespace Wrox.ProCSharp.AdvancedCSharp { delegate double DoubleOp(double x); class MainEntryPoint { static void Main() { DoubleOp [] operations = { new DoubleOp(MathsOperations.MultiplyByTwo), new DoubleOp(MathsOperations.Square) }; for (int i=0 ; i