Cơ chế ủy quyền

30 442 0
Cơ chế ủy quyền

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Cơ chế ủy quyền Cơ chế ủy quyền Bởi: Khuyet Danh Trong thời kỳ đầu máy tính, chương trình thực theo trình tự xử lý bước hoàn thành, người dùng thực tương tác làm hạn chế điều khiển hoạt động khác chương trình tương tác với người dùng chấm dứt Tuy nhiên, ngày với mô hình lập trình giao diện người dùng đồ họa (GUI: Graphical User Interface) đòi hỏi cách tiếp cận khác, biết lập trình điều khiển kiện (event-driven programming) Chương trình đại đưa giao diện tương tác với người dùng sau chờ cho người sử dụng kích hoạt hành động Người sử dụng thực nhiều hành động khác như: chọn mục chọn menu, nhấn nút lệnh, cập nhật ô chứa văn bản, Mỗi hành động dẫn đến kiện (event) sinh Một số kiện khác xuất mà không cần hành động trực tiếp người dùng Các kiện xuất thiết bị đồng hồ máy tính phát theo chu kỳ thời gian, thư điện tử nhận, hay đơn giản báo hành động chép tập tin hoàn thành, Một kiện đóng gói ý tưởng “chuyện xảy ra” chương trình phải đáp ứng lại với kiện Cơ chế kiện ủy quyền gắn liền với nhau, kiện xuất cần phải phân phát kiện đến trình xử lý kiện tương ứng Thông trường trình xử lý kiện thực thi C# ủy quyền Ủ y quyền cho phép lớp yêu cầu lớp khác làm công việc đó, thực công việc phải báo cho lớp biết Ủy quyền co thể sử dụng để xác nhận phương thức biết lúc thực thi chương trình, tìm hiểu kỹ vấn đề phần chương Ủy quyền (delegate) Trong ngôn ngữ C#, ủy quyền lớp đối tượng (first-class object), hỗ trợ đầy đủ ngôn ngữ lập trình Theo kỹ thuật ủy quyền kiểu liệu tham chiếu dùng để đóng gói phương thức với tham số kiểu trả xác định Chúng ta đóng gói phương thức thích hợp vào đối tượng ủy quyền Trong ngôn ngữ C++ ngôn ngữ khác, làm điều cách sử dụng trỏ hàm (function pointer) trỏ đến hàm thành viên Không giống 1/30 Cơ chế ủy quyền trỏ hàm C/C++, ủy quyền hướng đối tượng, kiểu liệu an toàn (type-safe) bảo mật Một điều thú vị hữu dụng ủy quyền không cần biết không quan tâm đến lớp đối tượng mà tham chiếu tới Điều cần quan tâm đến đối tượng đối mục phương thức kiểu trả phải phù hợp với đối tượng ủy quyền khai báo Để tạo ủy quyền ta dùng từ khóa delegate theo sau kiểu trả tên phương thức ủy quyền đối mục cần thiết: public delegate int WhichIsFirst(object obj1, object obj2); Khai báo định nghĩa ủy quyền tên WhichIsFirst, đóng gói phương thức lấy hai tham số kiểu object trả giá trị int Một mà ủy quyền định nghĩa, đóng gói phương thức thành viên việc tạo thể ủy quyền này, truyền vào phương thức có khai báo kiểu trả đối mục cần thiết Từ phần sau quy ước sử dụng qua lại hai từ uỷ quyền delegate với Sử dụng ủy quyền để xác nhận phương thức lúc thực thi Ủ y quyền biết dùng để xác định loại phương thức dùng để xử lý kiện để thực callback chương trình ứng dụng Chúng sử dụng để xác định phương thức tĩnh instance phương thức mà trước chương trình thực Giả sử minh họa sau, muốn tạo lớp chứa đơn giản gọi Pair lớp lưu giữ xếp hai đối tượng truyền vào cho chúng Tạm thời lúc biết loại đối tượng mà Pair lưu giữ Nhưng cách tạo phương thức bên đối tượng thực việc xếp ủy quyền, ủy quyền thực việc thứ tự cho thân đối tượng Những đối tượng khác xếp khác Ví dụ, Pair chứa đối tượng đếm xếp theo thứ tự số, Pair nút lệnh button theo thứ tự alphabe tên chúng Mong muốn người tạo lớp Pair đối tượng bên Pair phải có trách nhiệm cho biết thứ tự chúng thứ tự thứ hai Để làm điều này, phải đảm bảo đối tượng bên Pair phải cung cấp phương thức cho biết cách xếp đối tượng 2/30 Cơ chế ủy quyền Chúng ta định nghĩa phương thức yêu cầu việc tạo ủy quyền, ủy quyền định nghĩa ký pháp kiểu trả phương thức đối tượng (như button) để cung cấp cho phép Pair xác định đối tượng đến trước đối tượng thứ hai Lớp Pair định nghĩa ủy quyền, WhichIsFirst Phương thức Sort lấy tham số thể WhichIsFirst Khi đối tượng Pair cần biết thứ tự đối tượng bên yêu cầu ủy quyền truyền vào hai đối tượng chứa tham số Trách nhiệm việc xác định thứ tự hai đối tượng trao cho phương thức đóng gói ủy quyền Để kiểm tra thực chế ủy quyền, tạo hai lớp, lớp Cat lớp Student Hai lớp có điểm chung với nhau, ngoại trừ hai thực thi phương thức đóng gói WhichIsFirst Do hai đối tượng lưu giữ bên đối tượng Pair Trong chương trình thử nghiệm tạo hai đối tượng Student hai đối tượng Cat lưu chúng vào đối tượng Pair Sau tạo đối tượng ủy quyền để đóng gói phương thức chúng, phương thức phải phù hợp với ký pháp kiểu trả ủy quyền Sau yêu cầu đối tượng Pair xếp đối tượng Student Cat, ta làm bước sau: Bắt đầu việc tạo phương thức khởi dựng Pair lấy hai đối tượng đưa chúng vào mảng riêng: public class Pair { // đưa vào đối tượng theo thứ tự public Pair( object firstObjectr, object secondObject) { thePair[0] = firstObject; thePair[1] = secondObject; } // biến lưu giữ hai đối tượng 3/30 Cơ chế ủy quyền private object[] thePair = new object[2]; } Tiếp theo phủ phương thức ToString() để chứa giá trị hai đối tượng mà Pair nắm giữ: public override string ToString() { // xuất thứ tự đối tượng thứ trước đối tượng thứ hai return thePair[0].ToString() +"," + thePair[1].ToString(); } Bây có hai đối tượng bên Pair xuất giá trị chúng hình Tiếp tục thực việc xếp in kết xếp Hiện không xác định loại đối tượng mà có, ủy quyền định thứ tự xếp cho thân đối tượng mà Pair lưu giữ bên Do vậy, yêu cầu đối tượng lưu giữ bên Pair thực việc kiểm tra xem đối tượng trước Phương thức lấy hai tham số đối tượng trả giá trị kiểu liệt kê: theFirstComeFirst đối tượng đến trước theSecondComeFirst giá trị thứ hai đến trước Những phương thức yêu cầu đóng gói ủy quyền WhichIsFirst định nghĩa bên lớp Pair: public delegate comparison WhichIsFirst( object obj1, object obj2); Giá trị trả kiểu comparison kiểu liệt kê: public enum comparison { theFirstComesFirst = 1, theSecondComesFirst = } 4/30 Cơ chế ủy quyền Bất phương thức tĩnh lấy hai tham số đối tượng object trả kiểu comparison đóng gói ủy quyền vào lúc thực thi Lúc định nghĩa phương thức Sort cho lớp Pair: public void Sort( WhichIsFirst theDelegateFunc) { if (theDelegateFunc(thePair[0], comparison.theSecondComeFirst) thePair[1]) == { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } } Phương thức lấy tham số: ủy quyền có kiểu WhichIsFirst với tên theDelegateFunc Phương thức Sort giao phó trách nhiệm định thứ tự đến trước sau hai đối tượng bên Pair đến phương thức đóng gói ủy quyền Bên thân Sort, phương thức ủy quyền gọi trả giá trị, giá trị hai giá trị liệt kê comparison Nếu giá trị trả theSecondComesFirst, đối tượng bên Pair hoán đổi vị trí, trường hợp ngược lại không làm Hãy tưởng tượng xếp Student theo tên Chúng ta viết phương thức trả theFirstComesFirst tên sinh viên đến trước theSecondComesFirst tên sinh viên thứ hai đến trước Nếu đưa vào “Amy, Beth” phương thức trả kết theFirstComesFirst Và ngược lại truyền “Beth, Amy” kết trả theSecondComesFirst Khi nhận kết theSecondComesFirst, phương thức Sort đảo hai đối tượng mảng, thiết lập Amy vị trí đầu Beth vị trí thứ hai Tiếp theo thêm phương thức ReverseSort, phương thức đặt mục mảng theo thứ tự đảo ngược lại: 5/30 Cơ chế ủy quyền public void ReverseSort( WhichIsFirst theDeleagteFunc) { if ( theDelegateFunc( thePair[0], ==comparison.theFirstComesFirst) thePair[1]) { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } } Việc thực tương tự phương thức Sort Tuy nhiên, phương thức thực việc hoán đổi phương thức ủy quyền xác định đối tượng trước tới trước Do vậy, kết thực phương thức đối tượng thứ hai đến trước Lúc truyền vào “Amy, Beth”, phương thức ủy quyền trả theFirstComesFirst, phương thức ReverseSort hoán đổi vị trí hai đối tượng này, thiết lập Beth đến trước Điều cho phép sử dụng phương thức ủy quyền tương tự Sort, mà không cần yêu cầu đối tượng hỗ trợ phương thức trả giá trị ngược Lúc điều cần thiết tạo vài đối tượng để xếp Ta tạo hai lớp đối tượng đơn giản sau: lớp đối tượng Student lớp đối tượng Cat Gán cho đối tượng Student tên vào lúc tạo: public class Student { public Student (string name) { this.name = name; } } Lớp đối tượng Student yêu cầu hai phương thức, phương thức phủ ToString(), phương thức khác đóng gói phương thức ủy quyền Lớp Student phải phủ phương thức ToString() phương thức ToString() lớp Pair sử dụng cách xác Việc thực thi phức tạp mà đơn trả tên sinh viên: public override string ToString() { 6/30 Cơ chế ủy quyền return name; } Student phải thực thi phương thức hỗ trợ cho Pair.Sort() ủy quyền xác định thứ tự hai đối tượng xem đối tượng đến trước: public static comparison WhichStudentComesFirst(Object o1, Object o2) { Student s1 = (Student) o1; Student s2 = (Student) o2; return ( String.Compare( s1.name, comparison.theFirstComesFirst comparison.theSecondComesFirst); s2.name) c2.weight ? theSecondComesFirst : theFirstComesFirst; } public override string ToString() { return weight.ToString(); } // biến lưu giữ trọng lượng private int weight; } Cũng tương tự lớp Student lớp Cat phủ phương thức ToString() thực thi phương thức tĩnh với cú pháp tương ứng với phương thức ủy quyền Và lưu ý phương thức ủy quyền Student Cat không tên với Chúng ta không cần thiết phải làm tên gán đến phương thức ủy quyền lúc thực thi.Ví dụ minh họa sau trình bày cách phương thức ủy quyền gọi Làm việc với ủy quyền namespace Programming_CSharp 8/30 Cơ chế ủy quyền { using System; // khai báo kiểu liệt kê public enum comparison { theFirstComesFirst =1, theSecondComesFirst = } // lớp Pair đơn giản lưu giữ đối tượng public class Pair { // khai báo ủy quyền public delegate object obj2); comparison WhichIsFirst( object obj1, // truyền hai đối tượng vào khởi dựng public Pair( object firstObject, object secondObject) { thePair[0] = firstObject; thePair[1] = secondObject; } // phương thức xếp thứ tự hai đối tượng // theo tiêu chuẩn đối tượng public void Sort( WhichIsFirst theDelegateFunc) { 9/30 Cơ chế ủy quyền if (theDelegateFunc(thePair[0], ==comparison.theSecondComesFirst) thePair[1]) { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } } // phương thức xếp hai đối tượng theo // thứ tự nghịch đảo lại tiêu chuẩn xếp public void ReverseSort( WhichIsFirst theDelegateFunc) { if (theDelegateFunc( thePair[0], ==comparison.theFirstComesFirst) thePair[1]) { object temp = thePair[0]; thePair[0] = thePair[1]; thePair[1] = temp; } } // yêu cầu hai đối tượng đưa giá trị public override string ToString() { 10/30 Cơ chế ủy quyền Bây ta có đối tượng ủy quyền, truyền ủy quyền cho phương thức Sort đối tượng Pair, sau phương thức ReverseSort Kết xuất hình: Sau sap xep studentPair : Ba, Thao Sau sap xep nguoc studentPair : Thao, Ba Sau sap xep catPair : 2, Sau sap xep nguoc catPair : 5, Ủy quyền tĩnh Như thấy ví dụ minh hoạ 11.1 trước hai thể phương thức ủy quyền khai báo bên lớp gọi (chính xác hàm Main Test) Điều không cần thiết ta sử dụng khai báo ủy quyền tĩnh từ hai lớp Student Cat Do ta bổ sung lớp Student cách thêm vào: public static readonly Pair.WhichIsFirst OrderStudents =new Pair.WhichIsFirst(Student.WhichStudentComesFirst); Ý nghĩa lệnh tạo ủy quyền tĩnh tên OrderStudents có thuộc tính đọc readonly Việc thêm vào thuộc tính readonly để ghi trường tạo không bổ sung sau Tương tự tạo ủy quyền tĩnh cho Cat sau: public static readonly Pair.WhichIsFirst OderCats = new Pair.WhichIsFirst( Cat.WhichCatComesFirst); Bây có hai trường tĩnh diện bên lớp Student Cat, gắn với phương thức tương ứng bên lớp Sau thực ủy quyền mà không cần khai báo thể ủy quyền cục Việc chuyển ủy quyền thực lệnh in đậm sau: studentPair.Sort( theStudentDelegate); Console.WriteLine("Sau sap xep studentPair\t\t:{0}", studentPair.ToString()); studentPair.ReverseSort(Student.OrderStudents); 16/30 Cơ chế ủy quyền Console.WriteLine("Sau t:{0}", sap xep nguoc studentPair\t\ studentPair.ToString()); catPair.Sort( theCatDelegate); Console.WriteLine("Sau catPair.ToString()); sap xep catPair\t\t:{0}", catPair.ReverseSort(Cat.OrderCats); Console.WriteLine("Sau sap xep nguoc catPair\t\t:{0}", catPair.ToString()); Kết thực tương tự ví dụ trước Sử dụng ủy quyền thuộc tính Đối với ủy quyền tĩnh chúng bắt buộc phải tạo thể hiện, tính chất tĩnh, mà không cần biết chúng có sử dụng hay không, lớp Student Cat ví dụ bên Chúng ta phát triển lớp tốt cách thay ủy quyền tĩnh từ trường thành thuộc tính Với lớp Student ta chuyển khai báo: public static readonly Pair.WhichIsFirst OrderStudent =new Pair.WhichIsFirst( Student.WhichStudentComesFirst); thành khai báo sau: public static Pair.WhichIsFirst OrderStudents { get { return new Pair.WhichIsFirst( WhichStudentComesFirst); } 17/30 Cơ chế ủy quyền } Tương tự thực thay với lớp Cat: public static Pair.WhichIsFirst OderCats { get { return new Pair.WhichIsFirst( WhichCatComesFirst); } } Khi truyền cho phương thức không thay đổi: studentPair.Sort( Student.OderStudents); catPair.Sort( Cat.OrderCats); Khi thuộc tính OrderStudents truy cập ủy quyền tạo ra: return new Pair.WhichIsFirst( WhichCatComesFirst); Điều quan trọng ủy quyền không tạo yêu cầu Việc cho phép lớp gọi (như lớp Test) định cần thiết sử dụng ủy quyền cho phép việc tạo ủy quyền trách nhiệm lớp Student hay lớp Cat Thiết lập thứ tự thi hành với mảng ủy quyền Ủ y quyền giúp tạo hệ thống người sử dụng định đến thứ tự hoạt động thực thi Giả sử có hệ thống xử lý ảnh ảnh thao tác phương pháp định nghĩa tốt là: làm mờ, làm đậm, xoay, lọc ảnh, Giả sử rằng, thứ tự sử dụng hiệu ứng áp dụng cho ảnh quan trọng Người sử dụng muốn lựa chọn hiệu ứng từ menu, chọn tất hiệu ứng tùy thích, sau yêu cầu xứ lý ảnh thực hiệu ứng mà xác định 18/30 Cơ chế ủy quyền Chúng ta tạo ủy quyền cho hoạt động sau thêm chúng vào tập hợp sắp, mảng chẳng hạn, theo thứ tự mà ta muốn chúng thực thi Một tất ủy quyền tạo đưa vào tập hợp, dễ dàng lặp qua thành phần mảng, thực thi phương thức ủy quyền Chúng ta bắt đầu việc xây dựng lớp Image thể ảnh xử lý lớp ImageProcessor: public class Image { public Image() { Console.WriteLine("An image created"); } } Chúng ta tưởng tượng việc xuất chuỗi tương ứng với việc tạo ảnh gif hay jpeg hay Sau lớp ImageProcessor khai báo ủy quyền Dĩ nhiên định nghĩa ủy quyền riêng trả kiểu liệu hay lấy tham số mà muốn Trong ví dụ định nghĩa ủy quyền đóng gói phương thức giá trị trả không nhận tham số hết: public delegate void DoEffect(); Tiếp tục lớp ImageProcessor khai báo sô phương thức, phương thức phù hợp với ký pháp kiểu trả khai báo ủy quyền: public static void Blur() { Console.WriteLine("Blurring image"); } public static void Filter() { Console.WriteLine("Filtering image"); } public static void Sharpen() { Console.WriteLine("Sharpening image"); } public static void Rotate() { Console.WriteLine("Rotating image"); } 19/30 Cơ chế ủy quyền Lớp ImageProcessor cần thiết có mảng để lưu giữ ủy quyền mà người sử dụng chọn, biến lưu giữ số hiệu ứng chọn dĩ nhiên có biến ảnh để xử lý: DoEffect[] arrayOfEffects; Image image; int numEffectsRegistered = 0; ImageProcessor cần phương thức để thêm ủy quyền vào mảng: public void AddToEffects( DoEffect theEffect) { if (numEffectsRegistered >=0) { throw new Exception("Too many members in array"); } arrayOfEffects[numEffectsRegistered ++] = theEffect; } Ngoài cần phương thức thật gọi ủy quyền này: public void ProcessImage() { for (int i = 0; i < numEffectsRegistered; i++) { arrayOfEffects[i](); } } Cuối cùng, khai báo ủy quyền tĩnh, để client gọi, chặn chúng lại để xử lý phương thức: public DoEffect BlurEffect = new DoEffect(Blur); public DoEffect SharpenEffect = new DoEffect(Sharpen); public DoEffect FilterEffect = new DoEffect(Filter); public DoEffect RotateEffect = new DoEffect(Rotate); Việc chọn thao tác diễn trình tương tác thành phần giao diện người sử dụng Trong ví dụ mô cách chọn hiệu ứng, thêm chúng vào mảng, ProcessImage Sử dụng mảng ủy quyền namespace Programming_CSharp { using System; 20/30 Cơ chế ủy quyền // khai báo lớp ảnh public class Image { public Image() { Console.WriteLine("An image created"); } } // lớp xử lý ảnh public class ImageProcessor { // khai báo ủy quyền public delegate void DoEffect(); // tạo ủy quyền tĩnh public DoEffect BlurEffect = new DoEffect(Blur); public DoEffect SharpenEffect = new DoEffect(Sharpen); public DoEffect FilterEffect = new DoEffect(Filter); public DoEffect RotateEffect = new DoEffect(Rotate); // khởi dựng khởi tạo ảnh mảng public ImageProcessor(Image image) { this.image = image; arrayOfEffects = new DoEffect[10]; 21/30 Cơ chế ủy quyền } // thêm hiệu ứng vào mảng public void AddToEffects( DoEffect theEffect) { if (numEffectsRegistered >=0) { throw new Exception("Too many members in array"); } arrayOfEffects[numEffectsRegistered ++] = theEffect; } // phương thức xử lý ảnh public static void Blur() { Console.WriteLine("Blurring image"); } public static void Filter() { Console.WriteLine("Filtering image"); } public static void Sharpen() { Console.WriteLine("Sharpening image"); 22/30 Cơ chế ủy quyền } public static void Rotate() { Console.WriteLine("Rotating image"); } // gọi ủy quyền để thực hiệu ứng public void ProcessImage() { for (int i = 0; i < numEffectsRegistered; i++) { arrayOfEffects[i](); } } // biến thành viên private DoEffect[] arrayOfEffects; private Image image; private int numEffectsRegistered = 0; } // lớp Test để kiểm chứng chương trình public class Test { public static void Main() 23/30 Cơ chế ủy quyền { Image theImage = new Image(); // GUI để thực chọn lần // lượt hành động thực ImageProcessor theProc = new ImageProcessor(theImage); theProc.AddToEffects(theProc.BlurEffect); theProc.AddToEffects(theProc.FilterEffect); theProc.AddToEffects(theProc.RotateEffect); theProc.AddToEffects(theProc.SharpenEffect); theProc.ProcessImage(); } } } Kết quả: An image created Blurring image Filtering image Rotate image Sharpening image Trong ví dụ trên, đối tượng ImageProcessor tạo hiệu ứng thêm vào Nếu người dùng chọn làm mờ trước lọc ảnh, đơn giản đưa vào mảng ủy quyền theo thứ tự tương ứng Tương tự vậy, hành động lựa chọn người dùng mong muốn, ta đưa thêm nhiều ủy quyền vào tập hợp 24/30 Cơ chế ủy quyền Chúng ta tưởng tượng việc hiển thị thứ tự hành động danh sách listbox cho phép người sử dụng xếp lại phương thức, di chuyển chúng lên xuống danh sách Khi hành động xếp lại cần thay đổi thứ tự tập hợp Ngoài ta đưa hoạt động vào sở liệu sau đọc chúng lúc thực Ủy quyền dễ dàng cung cấp động cho ta phương thức gọi theo thứ tự xác định Multicasting Cơ chế multicasting cho phép gọi hai phương thức thực thi thông qua ủy quyền đơn Điều trở nên quan trọng xử lý kiện, thảo luận phần cuối chương Mục đích có ủy quyền gọi thực nhiều phương thức Điều hoàn toàn khác với việc có tập hợp ủy quyền, số chúng gọi phương thức Trong ví dụ trước, tập hợp sử dụng để lưu giữ ủy quyền khác Tập hợp thêm ủy quyền nhiều lần, sử dụng tập hợp để xếp lại ủy quyền điều khiển thứ tự hành động gọi Với Multicasting tạo ủy quyền đơn cho phép gọi nhiều phương thức đóng Ví dụ, nút lệnh nhấn muốn thực nhiều hàh động Để làm điều đưa cho button tập hợp ủy quyền, để sáng rõ dễ dàng tạo ủy quyền Multicast Bất ủy quyền trả giá trị void ủy quyền multicast, ta đối xử với ủy quyền bình thường không Hai ủy quyền Multicast kết hợp với phép toán cộng (+) Kết ủy quyền Multicast gọi đến tất phương thức thực thi nguyên thủy hai bên Ví dụ, giả sử Writer Logger ủy quyền trả giá trị void, dòng lệnh theo sau kết hợp chúng lại với tạo ủy quyền Multicast mới: myMulticastDelegate = Writer + Logger; Chúng ta thêm ủy quyền vào ủy quyền Multicast toán tử cộng (+=) Phép toán thêm ủy quyền phía bên phải toán tử vào ủy quyền Multicast bên trái Ví dụ minh họa sau, giả sử có Transmitter myMulticastDelegate ủy quyền, lệnh sau thực việc thêm ủy quyền Transmitter vào myMulticastDelegate: myMulticastDelegate += Transmitter; 25/30 Cơ chế ủy quyền Để hiểu rõ ủy quyền Multicast tạo sử dụng, bước tìm hiểu thông qua ví dụ 11.3 bên dưới, ví dụ minh họa tạo lớp có tên gọi MyClassWithDelegate lớp định nghĩa delegate, delegate lấy tham số chuỗi giá trị trả về: void delegate void StringDelegate( string s); Sau định lớp gọi MyImplementingClass lớp có ba phương thức, tất phương thức trả giá trị void nhận chuỗi làm tham số: WriteString, LogString, Transmitting Phương thức viết chuỗi xuất hình tiêu chuẩn, chuỗi thứ hai mô viết vào log file, phương thức thứ ba mô việc chuyển chuỗi qua Internet Chúng ta tạo thể delegate để gọi phương thức tương ứng: Writer("String passed to Writer\n"); Logger("String passed to Logger\n"); Transmitter("String passed to Transmitter\n"); Để xem cách kết hợp delegate, tạo thể delegate khác: MyClassWithDelegate.StringDelegate myMulticastDelegate; gán cho delegate kết phép cộng hai delegate cho trước: myMulticastDelegate = Writer + Logger; Tiếp theo thêm vào delegate delegate cách sử dụng toán tử (+=): myMulticastDelegate += Transmitter; Cuối cùng, thực việc xóa deleagate sử dụng toán tử (-=): DelegateCollector -= Logger; Sau toàn ví dụ minh họa Kết hợp delegate namespace Programming_CSharp 26/30 Cơ chế ủy quyền { using System; public class MyClassWithDelegate { // khai báo delegate public delegate void StringDelegate(string s); } public class MyImplementingClass { public static void WriteString( string s) { Console.WriteLine("Writing string {0}", s); } public static void LogString( string s) { Console.WriteLine("Logging string {0}", s); } public static void TransmitString( string s) { Console.WriteLine("Transmitting string {0}", s); } } 27/30 Cơ chế ủy quyền public class Test { public static void Main() { // định nghĩa StringDelegate MyClassWithDelegate.StringDelegate Transmitter; // định nghĩa Multicasting StringDelegate Writer, khác Logger, thực MyClassWithDelegate.StringDelegate myMulticastDelegate; // tạo thể delegate truyền vào phương thức thực thi Writer = new MyClassWithDelegate.StringDelegate( MyImplementingClass.WriteString); Logger = new MyClassWithDelegate.StringDelegate( MyImplementingClass.LogString); Transmitter = new MyClassWithDelegate.StringDelegate( MyImplementingClass.TransmitString); // gọi phương thức delegate Writer Writer("String passed to Writer\n"); // gọi phương thức delegate Logger Logger("String passed to Logger\n"); //gọi phương thức delegate Transmitter Transmitter("String passed to Transmitter\n"); // thông báo người dùng kết hợp hai delegate vào 28/30 Cơ chế ủy quyền // multicast delegate Console.WriteLine("myMulticastDelegate = Writer + Logger"); // kết hợp hai delegate myMulticastDelegate = Writer + Logger; // gọi phương thức delegate, hai phương thức thực myMulticastDelegate("First string passed to Collector"); // bảo với người sử dụng thêm delegate thứ vào // Multicast delegate Console.WriteLine("\nmyMulticastDeleagte += Transmitter"); // thêm delegate thứ ba vào myMulticastDelegate += Transmitter; // gọi thực thi Multicast delegate, lúc ba // phương thức gọi thực myMulticastDelegate("Second string passed to Collector"); // bảo với người sử dụng xóa delegate Logger Console.WriteLine("\nmyMulticastDelegate -= Logger"); // xóa delegate Logger myMulticastDelegate -= Logger; // gọi lại delegate, lúc thực hai phương thức myMulticastDelegate("Third string passed to Collector"); }// end Main }// end class }// end namespace 29/30 Cơ chế ủy quyền Writing string String passed to Writer Logging string String passed to Logge Transmitting string String passed to Transmitter myMulticastDelegate = Writer + Logger Writing string First string passed to Collector Logging string First string passed to Collector myMulticastDelegate += Transmitter Writing string Second string passed to Collector Logging string Second string passed to Collector Transmitting string Second string passed to Collector myMulticastDelegate -= Logger Writing string Third string passed to Collector Transmitting string Third string passed to Collector Trong ví dụ trên, thể delegate định nghĩa ba delegate Writer, Logger, Transmitter gọi Delegate thứ tư myMulticastDelegate gán cách kết hợp hai delegate đầu, gọi, dẫn đến hai delegate gọi Khi delegate thứ ba thêm vào, kết myMulticastDelegate gọi tất ba phương thức delegate thực Cuối cùng, Logger xóa khỏi delegate, myMulticastDelegate gọi có hai phương thức thực thi Multicast delegate thể tốt việc ứng dụng xử lý kiện Khi kiện ví dụ nút lệnh nhấn, multicast delegate tương ứng gọi đến loạt phương thức xử lý kiện để đáp ứng lại với kiện 30/30 [...]... tập hợp các ủy quyền, nhưng để sáng rõ hơn và dễ dàng hơn là tạo một ủy quyền Multicast Bất cứ ủy quyền nào trả về giá trị void là ủy quyền multicast, mặc dù vậy ta có thể đối xử với nó như là ủy quyền bình thường cũng không sao Hai ủy quyền Multicast có thể được kết hợp với nhau bằng phép toán cộng (+) Kết quả là một ủy quyền Multicast mới và gọi đến tất cả các phương thức thực thi nguyên thủy của cả... hai bên Ví dụ, giả sử Writer và Logger là ủy quyền trả về giá trị void, dòng lệnh theo sau sẽ kết hợp chúng lại với nhau và tạo ra một ủy quyền Multicast mới: myMulticastDelegate = Writer + Logger; Chúng ta cũng có thể thêm những ủy quyền vào trong ủy quyền Multicast bằng toán tử cộng bằng (+=) Phép toán này sẽ thêm ủy quyền ở phía bên phải của toán tử vào ủy quyền Multicast ở bên trái Ví dụ minh họa... khác với việc có một tập hợp các ủy quyền, vì mỗi trong số chúng chỉ gọi được duy nhất một phương thức Trong ví dụ trước, tập hợp được sử dụng để lưu giữ các ủy quyền khác nhau Tập hợp này cũng có thể thêm một ủy quyền nhiều hơn một lần, và sử dụng tập hợp để sắp xếp lại các ủy quyền và điều khiển thứ tự hành động được gọi Với Multicasting chúng ta có thể tạo một ủy quyền đơn và cho phép gọi nhiều phương... mà anh ta đã xác định 18/30 Cơ chế ủy quyền Chúng ta có thể tạo những ủy quyền cho mỗi hoạt động và sau đó thêm chúng vào một tập hợp được sắp, như là một mảng chẳng hạn, theo một thứ tự mà ta muốn chúng thực thi Một khi tất cả các ủy quyền được tạo ra và đưa vào tập hợp, chúng ta dễ dàng lặp lần lượt qua các thành phần của mảng, và thực thi lần lượt từng phương thức ủy quyền Chúng ta bắt đầu bằng... mảng, và ProcessImage Sử dụng mảng ủy quyền namespace Programming_CSharp { using System; 20/30 Cơ chế ủy quyền // khai báo lớp ảnh public class Image { public Image() { Console.WriteLine("An image created"); } } // lớp xử lý ảnh public class ImageProcessor { // khai báo ủy quyền public delegate void DoEffect(); // tạo các ủy quyền tĩnh public DoEffect BlurEffect... vào ủy quyền Multicast ở bên trái Ví dụ minh họa như sau, giả sử có Transmitter và myMulticastDelegate là những ủy quyền, lệnh tiếp theo sau đây sẽ thực hiện việc thêm ủy quyền Transmitter vào trong myMulticastDelegate: myMulticastDelegate += Transmitter; 25/30 Cơ chế ủy quyền Để hiểu rõ ủy quyền Multicast được tạo ra và sử dụng, chúng ta sẽ từng bước tìm hiểu thông qua ví dụ 11.3 bên dưới, trong ví... Pair.WhichIsFirst( WhichCatComesFirst); Điều quan trọng ở đây là ủy quyền sẽ không được tạo cho đến khi nào nó được yêu cầu Việc này cho phép lớp gọi (như lớp Test) quyết định khi nào cần thiết sử dụng một ủy quyền nhưng vẫn cho phép việc tạo ủy quyền là trách nhiệm của lớp Student hay lớp Cat Thiết lập thứ tự thi hành với mảng ủy quyền Ủ y quyền có thể giúp chúng ta tạo ra một hệ thống trong đó người... hoạt động này vào trong cơ sở dữ liệu rồi sau đó đọc chúng lúc thực hiện Ủy quyền dễ dàng cung cấp động cho ta các phương thức được gọi theo một thứ tự xác định Multicasting Cơ chế multicasting cho phép gọi hai phương thức thực thi thông qua một ủy quyền đơn Điều này trở nên quan trọng khi xử lý các sự kiện, sẽ được thảo luận trong phần cuối của chương Mục đích chính là có một ủy quyền có thể gọi thực... Console.WriteLine("Meo {0}", catPair.ToString()); {0}", \t\t\t: // tạo ủy quyền Pair.WhichIsFirst theStudentDelegate = new Pair.WhichIsFirst( Student.WhichStudentComesFirst); Pair.WhichIsFirst theCatDelegate = new Pair.WhichIsFirst( Cat.WhichCatComesFirst); // sắp xếp dùng ủy quyền studentPair.Sort( theStudentDelegate); 13/30 Cơ chế ủy quyền Console.WriteLine("Sau khi sap xep studentPair\t\t:{0}", studentPair.ToString());... tĩnh của lớp Cat 15/30 Cơ chế ủy quyền Bây giờ ta đã có các đối tượng ủy quyền, chúng ta truyền ủy quyền đầu tiên cho phương thức Sort của đối tượng Pair, và sau đó là phương thức ReverseSort Kết quả được xuất ra màn hình: Sau khi sap xep studentPair : Ba, Thao Sau khi sap xep nguoc studentPair : Thao, Ba Sau khi sap xep catPair : 2, 5 Sau khi sap xep nguoc catPair : 5, 2 Ủy quyền tĩnh Như chúng ta đã ... đưa cho button tập hợp ủy quyền, để sáng rõ dễ dàng tạo ủy quyền Multicast Bất ủy quyền trả giá trị void ủy quyền multicast, ta đối xử với ủy quyền bình thường không Hai ủy quyền Multicast kết hợp... ủy quyền vào ủy quyền Multicast toán tử cộng (+=) Phép toán thêm ủy quyền phía bên phải toán tử vào ủy quyền Multicast bên trái Ví dụ minh họa sau, giả sử có Transmitter myMulticastDelegate ủy. .. myMulticastDelegate ủy quyền, lệnh sau thực việc thêm ủy quyền Transmitter vào myMulticastDelegate: myMulticastDelegate += Transmitter; 25/30 Cơ chế ủy quyền Để hiểu rõ ủy quyền Multicast tạo sử

Ngày đăng: 31/12/2015, 21:43

Mục lục

  • Cơ chế ủy quyền

  • Ủy quyền (delegate)

    • Sử dụng ủy quyền để xác nhận phương thức lúc thực thi

    • Sử dụng ủy quyền như thuộc tính

    • Thiết lập thứ tự thi hành với mảng ủy quyền

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan