Những chủ đề tiến bộ trong C# - Delegate – Phần 2 pps

10 277 0
Những chủ đề tiến bộ trong C# - Delegate – Phần 2 pps

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

Thông tin tài liệu

Những chủ đề tiến bộ trong C# Delegate – Phần 2 Định nghĩa delegate như sau: delegate bool CompareOp(object lhs, object rhs); Và xây dựng phương thức sort() là : static public void Sort(object [] sortArray, CompareOp gtMethod) Phần hướng dẫn cho phương thức này sẽ nói rõ rằng gtmethod phải tham chiếu đến 1 phương thức static có 2 đối số,và trả về true nếu giá trị của đối số thứ 2 là 'lớn hơn' ( nghĩa là năm sau trong mảng) đối số thứ nhất. mặc dù ta có thể sử dụng delegate ở đây,nhưng cũng có thể giải quyết vấn đề bằng cách sử dụng interface. .NET xây dựng 1 interface IComparer cho mục đích này. tuy nhiên , ta sử dụng delegate vì loại vấn đề này thì thường có khuynh hướng dùng delegate. Sau đây là lớp bublesorter : class BubbleSorter { static public void Sort(object [] sortArray, CompareOp gtMethod) { for (int i=0 ; i<sortArray.Length ; i++) { for (int j=i+1 ; j<sortArray.Length ; j++) { if (gtMethod(sortArray[j], sortArray[i])) { object temp = sortArray[i]; sortArray[i] = sortArray[j]; sortArray[j] = temp; } } } } } Để dùng lớp này ta cần định nghĩa 1 số lớp khác mà có thể dùng thiết lập mảng cần sắp xếp.ví dụ , công ty điện thoại có danh sách tên khách hàng, và muốn sắp danh sách theo lương.mỗi nhân viên trình bày bởi thể hiện của một lớp , Employee: class Employee { private string name; private decimal salary; public Employee(string name, decimal salary) { this.name = name; this.salary = salary; } public override string ToString() { return string.Format(name + ", {0:C}", salary); } public static bool RhsIsGreater(object lhs, object rhs) { Employee empLhs = (Employee) lhs; Employee empRhs = (Employee) rhs; return (empRhs.salary > empLhs.salary) ? true : false; } } Lưu ý để phù hợp với dấu ấn của delegate CompareOp, chúng ta phải định nghĩa RhsIsGreater trong lớp này lấy 2 đối tượng để tham khảo,hơn là tham khảo employee như là thông số.điều này có nghĩa là ta phải ép kiểu những thông số vào trong tham khảo employee để thực thi việc so sánh. Bây giờ ta viết mã yêu cầu sắp xếp : using System; namespace Wrox.ProCSharp.AdvancedCSharp { delegate bool CompareOp(object lhs, object rhs); class MainEntryPoint { static void Main() { Employee [] employees = { new Employee("Karli Watson", 20000), new Employee("Bill Gates", 10000), new Employee("Simon Robinson", 25000), new Employee("Mortimer", (decimal)1000000.38), new Employee("Arabel Jones", 23000), new Employee("Avon from 'Blake's 7'", 50000)}; CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsGreater); BubbleSorter.Sort(employees, employeeCompareOp); for (int i=0 ; i<employees.Length ; i++) Console.WriteLine(employees[i].ToString()); } } Chạy mã này sẽ thấy employees được sắp xếp theo lương BubbleSorter Bill Gates, £10,000.00 Karli Watson, £20,000.00 Arabel Jones, £23,000.00 Simon Robinson, £25,000.00 Avon from 'Blake's 7', £50,000.00 Mortimer, £1,000,000.38 Multicast delegate Đến lúc này mỗi delegate mà chúng ta sử dụng chỉ gói ghém trong 1 phương thức đơn gọi.gọi delegate nào thì dùng phương thức đó.nếu ta muốn gọi nhiều hơn 1 phương thức, ta cần tạo một lời gọi tường minh xuyên suốt delegate nhiều hơn một lần.tuy nhiên, 1 delegate có thể gói ghém nhiều hơn 1 phương thức. 1 delegate như vậy gọi là multicast delegate. nếu 1 multicast delegate được gọi, nó sẽ gọi liên tiếp những phương thức theo thứ tự.để làm điều này, delegate phải trả về là void.nếu ta dùng một delegate có kiểu trả về là void , trình biên dịch sẽ coi như đây là một multicast delegate.xem ví dụ sau , dù cú pháp giống như trước đây nhưng nó thực sự là một multicast delegate, operations, delegate void DoubleOp(double value); // delegate double DoubleOp(double value); // can't do this now class MainEntryPoint { static void Main() { DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo); operations += new DoubleOp(MathOperations.Square); Trong ví dụ trên muốn tham khảo đến 2 phương thức ta dùng mảng delegate. ở đây , đơn giản ta chỉ thêm 2 thao tác này vào trong cùng một multicast delegate.multiccast delegate nhận toán tử + và +=. nếu ta muốn , ta có thể mở rộng 2 dòng mã trên , có cùng cách tác động : DoubleOp operation1 = new DoubleOp(MathOperations.MultiplyByTwo); DoubleOp operation2 = new DoubleOp(MathOperations.Square); DoubleOp operations = operation1 + operation2; multicast delegate cũng biết toán tử - và -= để bỏ đi phương thức được gọi từ delegate. một muticast delegate là một lớp được dẫn xuất từ System.MulticastDelegate mà lại được dẫn xuất từ System.Delegate. System.MulticastDelegate có thêm những thành phần để cho phép nối những phương thức gọi cùng với nhau vào một danh sách. Minh hoạ cho sử dụng multicast delegate ta sử dụng lại ví dụ simpleDelegate biến nó thành một ví dụ mới MulticastDelegate. bởi vì ta cần delegate trả về kiểu void , ta phải viết lại những phương thức trong lớp Mathoperations ,chúng sẽ trình bày kết quả thay vì trả về : class MathOperations { public static void MultiplyByTwo(double value) { double result = value*2; Console.WriteLine( "Multiplying by 2: {0} gives {1}", value, result); } public static void Square(double value) { double result = value*value; Console.WriteLine("Squaring: {0} gives {1}", value, result); } } Để dàn xếp sự thay đổi này , ta viết lại ProcessAndDisplayNumber: static void ProcessAndDisplayNumber(DoubleOp action, double value) { Console.WriteLine("\nProcessAndDisplayNumber called with value = " + value); action(value); } Bây giờ thử multicast delegate ta vừa tạo : static void Main() { DoubleOp operations = new DoubleOp(MathOperations.MultiplyByTwo); operations += new DoubleOp(MathOperations.Square); ProcessAndDisplayNumber(operations, 2.0); ProcessAndDisplayNumber(operations, 7.94); ProcessAndDisplayNumber(operations, 1.414); Console.WriteLine(); } Bây giờ mỗi lần ProcessAndDisplayNumber được gọi ,nó sẽ trình bày 1 thông điệp để báo rằng nó được gọi câu lệnh sau:action(value); Sẽ làm cho mỗi phương thức gọi trong thể hiện delegate action được gọi liên tiếp nhau. Kết quả : MulticastDelegate ProcessAndDisplayNumber called with value = 2 Multiplying by 2: 2 gives 4 Squaring: 2 gives 4 ProcessAndDisplayNumber called with value = 7.94 Multiplying by 2: 7.94 gives 15.88 Squaring: 7.94 gives 63.0436 ProcessAndDisplayNumber called with value = 1.414 Multiplying by 2: 1.414 gives 2.828 Squaring: 1.414 gives 1.999396 Nếu dùng multicast delegate , ta nên nhận thức đến thứ tự phương thức được nối với nhau trong cùng một delegate sẽ được gọi là không xác định. do đó ta nên tránh viết mã mà những phương thức được gọi liên hệ với nhau theo một thứ tự cụ thể. . Những chủ đề tiến bộ trong C# Delegate – Phần 2 Định nghĩa delegate như sau: delegate bool CompareOp(object lhs, object rhs); Và xây. DoubleOp(MathOperations.Square); Trong ví dụ trên muốn tham khảo đến 2 phương thức ta dùng mảng delegate. ở đây , đơn giản ta chỉ thêm 2 thao tác này vào trong cùng một multicast delegate. multiccast delegate nhận. operation1 + operation2; multicast delegate cũng biết toán tử - và -= để bỏ đi phương thức được gọi từ delegate. một muticast delegate là một lớp được dẫn xuất từ System.MulticastDelegate mà lại

Ngày đăng: 30/07/2014, 18:20

Từ khóa liên quan

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

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

Tài liệu liên quan