Thuộc tính quan trọng của đối tượng Capture là thuộc tính Length, đây chính là chiều dài của chuỗi con được nắm giữ. Khi chúng ta hỏi Match chiều dài của nó, thì chúng ta sẽ nhận được Capture.Length do Match được dẫn xuất từ Group và đến lượt Group lại được dẫn xuất từ Capture. Mô hình kế thừa trong biểu thức quy tắc của .NET cho phép Match thừa hưởng những giao diện phương thức và thuộc tính của những lớp cha của nó....
Ngơn Ngữ Lập Trình C# Thuộc tính quan trọng đối tượng Capture thuộc tính Length, chiều dài chuỗi nắm giữ Khi hỏi Match chiều dài nó, nhận Capture.Length Match dẫn xuất từ Group đến lượt Group lại dẫn xuất từ Capture Mơ hình kế thừa biểu thức quy tắc NET cho phép Match thừa hưởng giao diện phương thức thuộc tính lớp cha Theo ý nghĩa này, Group Capture (Group is-a Capture), đối tượng Capture đóng gói ý tưởng nhóm biểu thức Đến luợt Match, Group (Match is-a Group), đóng gói tất nhóm biểu thức so khớp biểu thức quy tắc (Xem chi tiết chương 5: Kế thừa đa hình) Thơng thường, tìm thấy Capture tập hợp CaptureCollection; điều Chúng ta thử tìm hiểu vấn đề sau, gặp trường hợp phân tích chuỗi có nhóm tên cơng ty xuất hai lần Để nhóm chúng lại chuỗi tìm thấy tạo nhóm ? xuất hai nơi mẫu biểu thức quy tắc sau: Regex theReg = new Regex(@”(?(\d|\:)+)\s” + @”(?\S+)\s” + @”(?(\d|\.)+)\s” + @”(?\S+)\s”); Biểu thức quy tắc nhóm chuỗi hợp với mẫu so khớp time, chuỗi theo nhóm ip Giả sử dùng chuỗi sau để làm chuỗi tìm kiếm: string string1 = “10:20:30 IBM 127.0.0.0 HP”; Chuỗi chứa tên hai cơng ty hai vị trí khác nhau, kết thực chương trình sau: theMatch: 10:20:30 IBM 127.0.0.0 HP Time: 10:20:30 IP: 127.0.0.0 Company: HP Điều xảy ra? Tại nhóm Company thể giá trị HP Còn chuỗi đâu khơng tìm thấy? Câu trả lời xác mục thứ hai viết chồng mục đầu Tuy nhiên, Group lưu giữ hai giá trị Và ta dùng tập hợp Capture để lấy giá trị Ví dụ minh họa 10.9: Tìm hiểu tập hợp CaptureCollection namespace Programming_CSharp { using System; using System.Text.RegularExpressions; class Test 300 Xử Lý Chuỗi Ngơn Ngữ Lập Trình C# { public static void Main() { // tạo chuỗi để phân tích // lưu ý tên cơng ty xuất // hai nơi string string1 = “10:20:30 IBM 127.0.0.0 HP”; // biểu thức quy tắc với việc nhóm hai lần tên cơng ty Regex theReg = new Regex(@”(?(\d|\:)+)\s” + @”(?\S+)\s” + @”(?(\d|\ )+)\s” + @”(?\S+)\s”); // đưa vào tập hợp chuỗi tìm thấy MatchCollection theMatches = theReg.Matches( string1 ); // dùng vòng lặp để lấy kết foreach ( Match theMatch in theMatches) { if ( theMatch.Length !=0 ) { Console.WriteLine(“theMatch: {0}”, theMatch.ToString()); Console.WriteLine(“Tme: {0}”, theMatch.Groups[“time”]); Console.WriteLine(“IP{0}”, theMatch.Groups[“ip”]); Console.WriteLine(“Company: {0}”, theMatch.Groups[“company”]); // lặp qua tập hợp Capture để lấy nhóm company foreach ( Capture cap in theMatch.Groups[“Company”].Captures) { Console.WriteLine(“Capture: {0}”, cap.ToString()); }// end foreach }// end if }// end foreach }// end Main }// end class }// end namespace Kết quả: theMatch: 10:20:30 IBM 127.0.0.0 HP Time: 10:20:30 IP: 127.0.0.0 301 Xử Lý Chuỗi Ngôn Ngữ Lập Trình C# Company: HP Capture: IBM Capture: HP Trong đoạn vòng lặp cuối cùng: foreach ( Capture cap in theMatch.Groups[“Company”].Captures) { Console.WriteLine(“Capture: {0}”, cap.ToString()); }// end foreach Đoạn lặp lặp qua tập hợp Capture nhóm Company Chúng ta thử tìm hiểu cách phân tích sau Trình biên dịch bắt đầu tìm tập hợp mà chúng thực việc lặp theMatch đối tượng có tập hợp tên Groups Tập hợp Groups có mục đưa chuỗi trả đối tượng Group Do vậy, dòng lệnh sau trả đối tượng đơn Group: theMatch.Groups[“company”]; Đối tượng Group có tập hợp tên Captures, dịng lệnh tiếp sau trả tập hợp Captures cho Group lưu giữ Groups[“company”] bên đối tượng theMatch: theMatch.Groups[“company”].Captures Vòng lặp foreach lặp qua tập hợp Captures, lấy thành phần gán cho biến cục cap, biến có kiểu Capture Chúng ta xem từ kết có hai thành phần lưu giữ : IBM HP Chuỗi thứ hai viết chồng lên chuỗi thứ nhóm, hiển thị giá trị thứ hai HP Tuy nhiên, việc sử dụng tập hợp Captures thu hai giá trị lưu giữ Câu hỏi trả lời Câu hỏi 1: Những tóm tắt chuỗi? Trả lời 1: Chuỗi kiểu liệu thường sử dụng lập trình Trong ngơn ngữ C#, chuỗi hỗ trợ mạnh thơng qua lóp chuỗi biểu thức quy tắc Chuỗi kiểu liệu tham chiếu, chứa ký tự Unicode Các thao tác đối tượng chuỗi không làm thay đổi giá trị chuỗi mà ta nhận kết trả Tuy nhiên, C# cung cấp lớp StringBuilder cho phép thao tác trực tiếp để bổ sung chuỗi Câu hỏi 2: Biểu thức quy tắc gì? Trả lời 2: Biểu thức quy tắc ngôn ngữ dùng để mô tả thao tác văn Một biểu thức quy tắc thường áp dụng cho chuỗi văn hay tồn tài liệu Kết việc áp dụng biểu thức quy tắc ta nhận chuỗi kết quả, chuỗi chuỗi chuỗi áp dụng chuỗi bổ sung từ chuỗi ban đầu Câu hỏi 3: Thao tác thường xuyên thực chuỗi thao tác nào? 302 Xử Lý Chuỗi Ngơn Ngữ Lập Trình C# Trả lời 3: Như bên trên, thao tác thường xuyên thực chuỗi tìm kiếm chuỗi thỏa quy tắc Một ngơn ngữ mạnh thao tác chuỗi, chắn phải cung cấp nhiều phương thức thao tác tốt để tìm kiếm chuỗi theo quy tắc Ngôn ngữ C# mạnh điểm này, chúng thừa hưởng từ lớp thao tác chuỗi NET Câu hỏi thêm Câu hỏi 1: Có cách tạo chuỗi ngơn ngữ C#? Câu hỏi 2: Chuỗi Verbatim chuỗi nào? Hãy cho vài ví dụ minh họa chuỗi diễn giải ý nghĩa chúng? Câu hỏi 3: Sự khác chuỗi tạo từ đối tượng string StringBuilder? Câu hỏi 4: Khi nên dùng chuỗi tạo từ lớp string StringBuilder? Câu hỏi 5: Một biểu thức quy tắc có kiểu ký tự? Câu hỏi 6: Một biểu thức quy tắc sau so khớp điều gì? ^(Name|Address|Phone|Fax): Bài tập Bài tập 1: Viết chương trình cho phép người dùng nhập vào chuỗi Sau đếm số ký tự xuất ký tự chuỗi ví dụ sau: ‘a’ : ‘g’ : ‘2’ : Bài tập 2: Viết chương trình tìm chuỗi chuỗi cho trước Chương trình cho phép người dùng nhập vào chuỗi, chuỗi cần tìm Kết chuỗi có tìm thấy hay khơng, tìm thấy đưa vị trí tìm thấy Bài tập 3: Viết chương trình tìm số lần xuất chuỗi chuỗi cho trước Chương trình cho phép người dùng nhập vào chuỗi chuỗi cần đếm Kết hiển thị chuỗi, chuỗi vị trí mà chuỗi xuất chuỗi Bài tập 4: Viết chương trình cho phép người dùng nhập vào chuỗi, thực việc đảo ký tự chuỗi theo thứ tự ngược lại Bài tập 5: Viết chương trình cắt từ có nghĩa câu Ví dụ cho từ: “Thuc hanh lap trinh” cắt thành chữ: “Thuc”, “hanh”, “lap”, “trinh” Bài tập 6: Hãy viết chương trình sử dụng biểu thức quy tắc để lấy chuỗi ngày/tháng/năm chuỗi cho trước? Cho phép người dùng nhập vào chuỗi dùng biểu thức quy tắc vừa tạo thực việc tìm kiếm Bài tập 7: Hãy viết chương trình sử dụng biểu thức quy tắc để lấy thời gian giờ:phút:giây chuỗi cho trước? Chương trình cho phép người dùng nhập vào chuỗi dùng biểu thức quy tắc vừa tạo để thực việc tìm kiếm 303 Xử Lý Chuỗi Ngơn Ngữ Lập Trình C# Chương 11 CƠ CHẾ ỦY QUYỀN - SỰ KIỆN • Ủ y quyền • • Sử dụng ủy quyền để xác nhận phương thức lúc thực thi • Ủ y quyền tĩnh • Dùng ủy quyền thuộc tính • Thiết lập thứ tự thi hành với mảng ủy quyền • Muticasting Sự kiện • • Cơ chế publishing – subscribing • Sự kiện & ủy quyền Câu hỏi & tập Trong lập trình thường đối diện với tình muốn thực hành động đó, chưa xác định xác phương thức hay kiện đối tượng Ví dụ nút lệnh button biết phải thơng báo cho vài đối tượng nhấn, khơng biết đối tượng hay nhiều đối tượng cần thông báo Tốt việc nối nút lệnh với đối tượng cụ thể, kết nối nút lệnh đến chế ủy quyền sau thực việc ủy quyền đến phương thức cụ thể thực thi chương trình 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 304 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# 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 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 Lưu ý: 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 305 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# 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 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 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; 306 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# thePair[1] = secondObject; } // biến lưu giữ hai đối tượng 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 = } 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], thePair[1]) == comparison.theSecondComeFirst) { 307 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình C# 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 hố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 cịn 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: public void ReverseSort( WhichIsFirst theDeleagteFunc) { if ( theDelegateFunc( thePair[0], thePair[1]) == comparison.theFirstComesFirst) { 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 hố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 308 Cơ Chế Ủy Quyền - Sự Kiện Ngơn Ngữ Lập Trình 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 khơng có phức tạp mà đơn trả tên sinh viên: public override string ToString() { 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, s2.name)