intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Tài Liệu Học Ngôn Ngữ Lập Trình C#_p6

Chia sẻ: Tailieu Upload | Ngày: | Loại File: PDF | Số trang:40

75
lượt xem
18
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tham khảo tài liệu 'tài liệu học ngôn ngữ lập trình c#_p6', công nghệ thông tin, kỹ thuật lập trình phục vụ nhu cầu học tập, nghiên cứu và làm việc hiệu quả

Chủ đề:
Lưu

Nội dung Text: Tài Liệu Học Ngôn Ngữ Lập Trình C#_p6

  1. Ngôn Ngữ Lập Trình C# { int P { get; set;} } và sau đó chú ng ta dẫn xu ất từ giao diện nà y ra một giao diện khác, IDerived, giao diện mới này làm ẩn thuộ c tính P với một phương thức mới P(): interface IDerived : IBase { new int P(); } Việc cài đ ặt này là một ý tưởng tốt, bây giờ chú ng ta có thể ẩn thu ộc tính P trong lớp cơ sở. Mộ t thực thi của giao diện dẫn xu ất nà y đòi hỏ i tối thiểu mộ t thành viên giao diện tường minh. Chúng ta có thể sử dụng thực thi tường minh cho thuộc tính củ a lớp cơ sở hoặc củ a phương thức d ẫn xuất, hoặc chú ng ta có thể sử dụng thự c thi tường minh cho cả hai. Do đó, ba phiên bản được viết sau đ ều hợp lệ: class myClass : IDerived { // thực thi tường minh cho thuộc tí nh cơ sở int IBase.p { get{...}} // thực thi ngầm đị nh phương thức dẫn xuất public int P() {...} } class myClass : IDerived { // thực thi ngầm đị nh cho thuộc tính cơ sở public int P { get{...}} // thực thi tường minh phương thức dẫn xuất int IDerived.P() {...} } class myClass : IDerived { // thực thi tường minh cho thuộc tí nh cơ sở int IBase.P { get{...}} // thực thi tường minh phương thức dẫn xuất int IDerived.P(){...} } Truy cập lớp không cho dẫn xuất và kiểu giá trị 201 Thực Thi Giao Diện
  2. Ngôn Ngữ Lập Trình C# Nói chung, việc truy cập những phương thức của mộ t giao diện thông qua việc gán cho giao diện thì thường được thích hơn. Ngoại trừ đố i với kiểu giá trị (như cấu trúc) hoặc với các lớp khô ng cho dẫn xu ất (sealed class). Trong trường hợp này, cách ưu chuộng hơn là gọi phương thức giao diện thông qua đối tượng. Khi chúng ta thực thi một giao diện trong mộ t cấu trú c, là chú ng ta đ ang thực thi nó trong mộ t kiểu d ữ liệu giá trị. Khi chú ng ta gán cho môt tham chiếu giao diện, có mộ t boxing ngầm định của đối tượng. Chẳng may khi chú ng ta sử dụng giao diện để bổ sung đối tượng, nó là một đố i tượng đ ã boxing, không phải là đố i tượng nguyên thủ y cần được bổ sung. Xa hơn nữa, nếu chú ng ta thay đ ổi kiểu dữ liệu giá trị, thì kiểu d ữ liệu được boxing vẫn khô ng thay đổ i. Ví dụ 8.6 tạo ra một cấu trúc và thực thi mộ t giao diện IStorable và minh họ a việc boxing ngầm định khi gán một cấu trú c cho mộ t tham chiếu giao diện.  Ví dụ 8.6: Tham chiếu đến kiểu dữ liệu giá trị. ----------------------------------------------------------------------------- using System; // khai báo một giao diện đơn interface IStorable { void Read(); int Status { get; set;} } // thực thi thông qua cấu trúc public struct myStruct : IStorable { public void Read() { Console.WriteLine(“Implementing IStorable.Read”); } public int Status { get { return status; } set { status = value; } } 202 Thực Thi Giao Diện
  3. Ngôn Ngữ Lập Trình C# // bi ến thành vi ên l ưu gi á trị thuộc tính Status private int status; } public class Tester { static void Main() { // tạo một đối tượng myStruct myStruct theStruct = new myStruct(); theStruct.Status = -1; // khởi tạo Console.WriteLine(“theStruct.Status: {0}”, theStruct.Status); // thay đổi gi á trị theStruct.Status = 2; Console.WriteLine(“Changed object”); Console.WriteLine(“theStruct.Status: {0}”, theStruct.Status); // gán cho giao di ện // boxing ngầm định IStorable isTemp = (IStorable) theStruct; // thi ết l ập giá trị thông qua tham chi ếu giao diện isTemp.Status = 4; Console.WriteLine(“Changed interface”); Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”, theStruct.Status, isTemp.Status); // thay đổi gi á trị một l ần nữa theStruct.Status = 6; Console.WriteLine(“Changed object.”); Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”, theStruct.Status, isTemp.Status); } } -----------------------------------------------------------------------------  Kết quả: theStruct.Status: -1 Changed object. theStruct.Status: 2 Changed interface theStruct.Status: 2, isTemp: 4 Changed object 203 Thực Thi Giao Diện
  4. Ngôn Ngữ Lập Trình C# theStruct.Status: 6, isTemp: 4 ----------------------------------------------------------------------------- Trong ví dụ 8.6, giao diện IStorable có một phương thứ c Read() và mô t thuộ c tính là Status. Giao diện nà y được thực thi bởi một cấu trúc tên là myStruct: public struct myStruct : IStorable Đoạn mã ngu ồn thú vị bên trong Tester. Chú ng ta b ắt đầu bằng việc tạo một thể hiện của cấu trú c và khởi tạo thuộc tính là –1, sau đó giá trị của status đ ược in ra:0 myStruct theStruct = new myStruct(); theStruct.Status = -1; // khởi tạo Console.WriteLine(“theStruct.Status: {0}”, theStruct.status); Kết qu ả là giá trị của status được thiết lập: theStruct.Status = -1; Kế tiếp chúng ta tru y cập thuộ c tính đ ể thay đổ i status, một lần nữa thông qua đối tượng giá trị: // thay đổi gi á trị theStruct.Status = 2; Console.WriteLine(“Changed object”); Console.WriteLine(“theStruct.Status: {0}”, theStruct.Status); kết qu ả chỉ ra sự thay đổ i: Changed object theStruct.Status: 2 Tại điểm này, chúng ta tạo ra một tham chiếu đ ến giao diện IStorable, một đố i tượng giá trị theStruct đ ược boxing ngầm và gán lại cho tham chiếu giao diện. Sau đó chúng ta dù ng giao diện đ ể thay đổ i giá trị của status bằng 4: // gán cho một giao di ện // boxing ngầm định IStorable isTemp = (IStorable) theStruct; // thi ết l ập giá trị thông qua tham chi ếu giao diện isTemp.Status = 4; Console.WriteLine(“Changed interface”); Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”, theStruct.Status, isTemp.Status); như chúng ta đã thấy kết qu ả thực hiện có một điểm khác biệt: Changed interface theStruct.Status: 2, isTemp: 4 Điều xả y ra là: đối tượng đ ược giao diện tham chiếu đến thay đổi giá trị status bằng 4, nhưng đối tượng giá trị cấu trú c không thay đ ổi.Thậm chí có nhiều thú vị hơn khi chú ng ta truy cập phương thức thông qua b ản thân đ ối tượng: 204 Thực Thi Giao Diện
  5. Ngôn Ngữ Lập Trình C# // than đổi giá trị l ần nữa theStruct.Status = 6; Console.WriteLine(“Changed object”); Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”, theStruct.Status, isTemp.Status); kết qu ả đối tượng giá trị thay đ ổi nhưng đ ối tượng đ ược boxing và được giao diện tham chịếu khô ng thay đổ i: Changed object theStruct.Status: 6, isTemp: 4 Ta thử xem đoạn mã IL để hiểu tham về cách thực hiện trên:  Ví dụ 8.7: MSIL phát sinh từ ví dụ 8.6. ----------------------------------------------------------------------------- method private hidebysig static void Main() il managed { .entrypoint // Code size 206 (0xce) .maxstack 4 .local ([0] value class myStruct theStruct, [1] class IStorable isTemp, [2] int32 V_2) IL_0000: ldloca.s theStruct IL_0002: iniobj myStruct IL_0008: ldloca.s theStruct IL_000a: ldc.i4.ml IL_000b: call instance void myStruct::set_status(int32) IL_0010: ldstr “theStruct.Status: {0}” IL_0015: ldloca.s theStruct IL_0017: call instance int32 myStruct::get_status() IL_001c: stloc.2 IL_001d: ldloca.s V_2 [mscorlib]System.Int32 IL_001f: box void [mscorlib] System.Console::WriteLine IL_0024: call (class System.String, class System.Object) IL_0029: ldloca.s theStruct IL_002b: ldc.i4.2 IL_002c: call instance void myStruct::set_status(int32) 205 Thực Thi Giao Diện
  6. Ngôn Ngữ Lập Trình C# IL_0031: ldstr “Changed object” IL_0036: call void [mscorlib]System.Console::WriteLine (class System.String) IL_003b: ldstr “theStruct.Status: {0}” IL_0040: ldloca.s theStruct IL_0042: call instance int32 myStruct::get_status() IL_0047: stloc.2 IL_0048: ldloca.s V_2 IL_004a: box [mscorlib]System.Int32 IL_004f: call void [mscorlib]System.Console::WriteLine (class System.String, class System.Object) IL_0054: ldloca.s theStruct IL_0056: box myStruct IL_005b: stloc.1 IL_005c: ldloc.1 IL_005d: ldc.i4.4 IL_005e: callvirt instance void IStorable::set_status(int32) IL_0063: ldstr “Changed interface” IL_0068: call void [mscorlib]System.Console::WriteLine (class System.String) IL_006d: ldstr “theStruct.Status: {0}, isTemp: {1}” IL_0072: ldloca.s theStruct IL_0074: call instance int32 mySystem::get_status() IL_0079: stloc.2 IL_007a: ldloca.s V_2 IL_007c: box [mscorlib]System.Int32 IL_0081: ldloc.1 IL_0082: callvirt instance int32 IStorable::get_status() IL_0087: stloc.2 IL_0088: ldloca.s V_2 [mscorli b]System.Int32 IL_008a: box void [mscorlib]System.Console::WriteLine IL_008f: call (class System.String, class System.Object, class System.Object) IL_0094: ldloca.s theStruct IL_0096: ldc.i4.6 IL_0097: call instance void myStruct::set_status(int32) IL_009c: ldstr “Changed object” IL_00a1: call void [mscorlib]System.Console::WriteLine 206 Thực Thi Giao Diện
  7. Ngôn Ngữ Lập Trình C# (class System.String) IL_00a6: ldstr “theStruct.Status: {0}, isTemp: {1}” IL_00ab: ldloca.s theStruct IL_00ad: call instance int32 myStruct::get_status() IL_00b2: stloc.2 IL_00b3: ldloca.s V_2 IL_00b5: box [mscorlib]System.Int32 IL_00ba: ldloc.1 IL_00bb: callvirt instance int32 IStorable::get_status() IL_00c0: stloc.2 IL_00c1: ldloca.s V_2 IL_00c3: box [mscorlib]System.Int32 IL_00c8: call void [mscorlib]System.Console::WriteLine (class System.String, class System.Object, class System.Object) IL_00cd: ret } // end fo method Tester::Main ----------------------------------------------------------------------------- Trong dò ng lệnh IL_00b, giá trị của status được thiết lập thông qua việc gọ i đối tượng giá trị. Tiếp theo chúng ta thấy lệnh gọi thứ hai ở dòng IL_0017. Lưu ý rằng việc gọi WriteLine() dẫn đến việc boxing một giá trị nguyên đ ể phương thứ c GetString của lớp object được gọ i. Điều muốn nhấn mạnh là ở dò ng lệnh IL_0056 khi một cấu trúc myStruct đã đ ược boxing. Việc boxing nà y tạo ra một kiểu dữ lịêu tham chiếu cho tham chiếu giao diện. Và điều quan trọ ng là ở dò ng IL_005e lúc này IStorable::set_status được gọ i chứ không phải là myStruct::setStatus. Điều quan trọng muốn trình bày ở đ ây là khi chúng ta thực thi một giao diện vớ i một kiểu giá trị, phải chắc chắn rằng truy cập các thành viên củ a giao diện thông qua đối tượng hơ n là thông qua một tham chiếu giao diện. Câu hỏi và trả lời Câu hỏi 1: So sánh giữa lớp và giao diện? Trả lời 1: Giao diện khá c với lớp ở một số đ iểm sau: giao diện không cung cấp bất cứ sự thực thi mã nguồn nào cả. Điều này sẽ được thực hiện tạ i các lớp thự c thi giao diện. Mộ t giao diện đưa ra chỉ để nói rằng có cung cấp một số sự xá c nhận hướng dẫn cho những điều gì đó xảy ra và không đ i vào chi tiết. Một điều khác nữa là tấ t cả cá c thành viên của giao diện được giả sử là public ngầm đ ịnh. Nếu chúng ta cố thay đổi thuộc tính truy cập của thành viên trong giao diện thì sẽ nhận được lỗi. Giao diện chỉ chứa những ph ương thức, thuộ c tính, sự kiện, ch ỉ mục. Và không chứa dữ liệu thành viên, bộ khởi d ựng, và bộ hủy. Chúng cũng không chứa bất cứ thành viên static nào cả. 207 Thực Thi Giao Diện
  8. Ngôn Ngữ Lập Trình C# Câu hỏi 2: Sự khác nhau giữa giao diện và lớp trừu tượng? Trả lời 2: Sự khác nhau cơ bản là sự kế thừa. Mộ t lớp có thể kế thừa nhiều giao diện cùng một lúc, nhưng không th ể kế thừa nhiều hơn mộ t lớp trừu tượng. Câu hỏi 3: Các lớp thực thi giao diện sẽ phải làm gì? Trả lời 3: Các lớp thực thi giao diện phả i cung cấp cá c phần thực thi chi tiết cho các phương thức, thuộ c tính, ch ỉ mụ c, sự kiện được khai báo trong giao diện. Câu hỏi 4: Có b ao nhiêu cách gọ i một phương thứ c được khai báo trong giao diện? Trả lời 4: Có 4 cách gọ i phương thức được khai báo trong giao diện:  Thông qua lớp cơ sở tham chiếu đ ến đối tượng của lớp dẫn xuấ t  Thông qua mộ t giao diện tạo từ lớp cơ sở tham chiếu đ ến đối tượng dẫn xuất  Thông qua mộ t đối tượng dẫn xuất  Thông qua giao diện tạo từ đối tượng dẫn xuấ t Câu hỏi 5: Các thành viên của giao diện có thể có những thuộ c tính truy cập nào? Trả lời 5: Mặ c định cá c thành viên của giao diện là public. Vì mục tiêu của giao diện là xâ y dựng cho các lớp khác sử dụng. Nếu chúng ta thay đổi thuộc tính nà y nh ư là internal, protected hay private thì sẽ gây ra lỗ i. Câu hỏi 6: Chú ng ta có thể tạo thể hiện của giao diện mộ t cách trực tiếp được khô ng? Trả lời 6: Không th ể tạo th ể hiện của giao diện trực tiếp bằng khai báo new được. Chúng ta chỉ có th ể tạo th ể hiện giao diện thông qua một phép gán với đối tượng thực thi giao diện. Câu hỏi thêm Câu hỏi 1: Toán tử is được dùng là m gì trong giao diện? Câu hỏi 2: Toán tử a s có lợi h ơn toán tử is về mặ t nào khi được sử dụng liện quan đ ến giao diện? Câu hỏi 3: Giao diện là kiểu dữ liệu tham chiếu hay kiểu giá trị? Câu hỏi 4: Khi thực thi giao diện với cấu trúc. Thì truy cập các thành viên của giao diện thông qua đối tượng hay thông qua tham chiếu giao diện là tốt nhất? Câu hỏi 5: Số giao diện có th ể được kế thừa cho một lớp? Câu hỏi 6: Việc thực thi giao diện tường minh là thự c thi như thế nào? Trong trường hợp nào thì cần thự c hiện tường minh? Bài tập Bài tập 1: Hã y viết mộ t giao diện khai báo một thuộc tính ID chứa chuỗi giá trị. Viết mộ t lớp Employee thực thi giao diện đó. Bài tập 2: Đọan mã nguồn sau đây có lỗi hã y sử lỗi và hã y cho biết tạ i sao có lỗi nà y. Sau khi sửa lỗi hã y viết mộ t lớp Circle thực thi giao diện này? ----------------------------------------------------------------------------- public interface IDimensions { 208 Thực Thi Giao Diện
  9. Ngôn Ngữ Lập Trình C# long width; long height; double Area(); double Circumference(); int Side(); } ----------------------------------------------------------------------------- Bài tập 3: Chương trình sau đây có lỗi hã y sử lỗ i, biên dịch và chạ y lại chương trình? Giải th ích tạ i sao chương trình có lỗi. ----------------------------------------------------------------------------- using System; interface IPoint { // Property signatures: int x { get; set; } int y { get; set; } } class MyPoint : IPoint { // Fields: private int myX; private int myY; // Constructor: public MyPoint(int x, int y) { myX = x; myY = y; } // Property implementation: public int x 209 Thực Thi Giao Diện
  10. Ngôn Ngữ Lập Trình C# { get { return myX; } set { myX = value; } } public int y { get { return myY; } set { myY = value; } } } class MainClass { private static void PrintPoint(IPoint p) { Console.WriteLine("x={0}, y={1}", p.x, p.y); } public static void Main() { MyPoint p = new MyPoint(2,3); Console.Write("My Point: "); PrintPoint(p); IPoint p2 = new IPoint(); PrintPoint(p2); } } ----------------------------------------------------------------------------- 210 Thực Thi Giao Diện
  11. Ngôn Ngữ Lập Trình C# Bài tập 4: Xâ y dựng một giao diện IDisplay có khai báo thuộ c tính Name kiểu chuỗ i. Hã y viết hai lớp Dog và Cat thực thi giao diện IDisplay, cho biết thuộ c tính Name là tên của đố i tư ợng. 211 Thực Thi Giao Diện
  12. Ngôn Ngữ Lập Trình C# Chương 9 MẢNG, CHỈ MỤC, VÀ TẬP HỢP  Mảng  Khai báo mảng  Giá trị mặc định  Truy cập các thành phần trong mả ng  Khởi tạo thành phần trong mảng  Sử dụng từ khóa params  Câ u lệnh lặp foreach  Mảng đa chiều  Mả ng đa chiều cùng kích thước  Mả ng đa chiều kích thước khác nhau  Chuyển đổi mả ng  System.Array  Bộ chỉ mục  Bộ chỉ mục và phép gán  Sử dụng kiểu chỉ số khá c  Giao diện tập hợp  Câ u hỏ i & bài tập Môi trường .NET cung cấp rất đ a dạng số lượng các lớp về tập hợp, bao gồm: Array, ArrayList, Queue, Stack, BitArray, NameValueCollection, và StringCollection. Trong số đó tập hợp đơn giản nhất là Array, đây là kiểu d ữ liệu tập hợp mà ngôn ngữ C# hỗ trợ xây d ựng sẵn. Chương này chú ng ta sẽ tìm hiểu cách làm việc với mảng một chiều, mảng đa chiều, và mảng các mảng (jagged array). Chú ng ta cũng đ ược giớ i thiệu phần chỉ mục indexer, đây là cách thiết lập để làm cho việc truy cập những thu ộc tính giố ng nhau trở nên đơn giản hơ n, mộ t lớp được chỉ mục thì giố ng như mộ t mảng. 212 Mảng, Chỉ Mục, và Tập Hợp
  13. Ngôn Ngữ Lập Trình C# .NET cũng cung cấp nhiều các giao diện, như IEnumerable và ICollection. Những phần thực thi của các giao diện nà y cung cấp các tiêu chu ẩn đ ể tương tác với các tập hợp. Trong chương này chú ng ta sẽ được cách sử d ụng hiệu quả củ a các giao diện. Cũ ng thông qua chương này chú ng ta sẽ được giới thiệu cách sử d ụng chung của các tập hợp trong .NET, bao gồm: ArrayList, Dictionary, Hashtable, Queue, và Stack. Mảng Mảng là một tập hợp có thứ tự của nhữ ng đố i tượng, tất cả các đố i tượng nà y cù ng một kiểu. M ảng trong ngôn ngữ C# có mộ t vài sự khác biệt so với mảng trong ngôn ngữ C++ và một số ngô n ngữ khác, bởi vì chú ng là nhữ ng đố i tượng. Điều này sẽ cung cấp cho mảng sử dụng các phương thức và những thu ộc tính. Ngô n ngữ C# cung cấp cú pháp chu ẩn cho việc khai b áo nhữ ng đố i tượng Array. Tuy nhiên, cái thật sự được tạo ra là đố i tượng của kiểu System.Array. Mảng trong ngôn ngữ C# kết hợp cú pháp khai b áo mảng theo kiểu ngôn ngữ C và kết hợp với định nghĩa lớp do đó thể hiện của mảng có thể truy cập nhữ ng phương thức và t hu ộc tính củ a System.Array. Mộ t số các thuộ c tính và phương thứ c củ a lớp System.Array Thà nh viên Mô tả Phương thức tĩnh public tìm kiếm một mảng một chiều đ ã BinarySearch() sắp thứ tự. Phương thức tĩnh public thiết lập các thành phần của mảng Clear() về 0 hay null. Phương thức tĩnh public đ ã nạp chồng thực hiện sao chép Copy() một vù ng của mảng vào mảng khác. Phương thức tĩnh public đ ã nạp chồng tạo một thể hiện mới CreateInstance() cho mảng Phương thức tĩnh public trả về chỉ mụ c củ a thể hiện đ ầu tiên IndexOf() chứa giá trị trong mảng mộ t chiều Phương thức tĩnh public trả về chỉ mụ c củ a thể hiện cu ối LastIndexOf() cùng củ a giá trị trong mảng mộ t chiều Phương thức tĩnh public đ ảo thứ tự củ a các thành phần trong Reverse() mảng một chiều Phương thức tĩnh public sắp xếp giá trị trong mảng một Sort() chiều. Thuộ c tính public giá trị bool thể hiện mảng có kích thước IsFixedSize cố định hay không. Thuộ c tính public giá trị bool thể hiện mảng chỉ đọc hay IsReadOnly khô ng 213 Mảng, Chỉ Mục, và Tập Hợp
  14. Ngôn Ngữ Lập Trình C# Thuộ c tính public giá trị bool thể hiện mảng có hỗ trợ IsSynchronized thread -safe Thuộ c tính public chiều dài củ a mảng Length Thuộ c tính public chứa số chiều của mảng Rank Thuộ c tính public chứa đố i tượng dùng để đồ ng b ộ truy cập SyncRoot trong mảng Phương thức public trả về IEnumerator GetEnumerator() Phương thức public trả về kích thước của một chiều cố định GetLength() trong mảng Phương thức public trả về cận d ưới của chiều xác đ ịnh trong GetLowerBound() mảng Phương thức public trả về cận trên của chiều xác định trong GetUpperBound() mảng Khởi tạo tất cả giá trị trong mảng kiểu giá trị bằng cách gọi Initialize() bộ khởi dụng mặc định của từng giá trị. Phương thức public thiết lập giá trị cho mộ t thành phần xác SetValue() đ ịnh trong mảng. Bảng 9.1: Cá c phương thức và thuộ c tính của System.Array. Khai báo mả ng Chúng ta có thể khai b áo một mảng trong C# với cú pháp theo sau: [] Ví dụ ta có khai b áo như sau: int[] myIntArray; Cặp d ấu ngo ặc vuô ng ([]) b áo cho trình biên dịch biết rằng chúng ta đang khai b áo một mảng. Kiểu d ữ liệu là kiểu củ a các thành phần chứa b ên trong mảng. Trong ví dụ bên trên. myIntArray được khai b áo là mảng số nguyên. Chúng ta tạo thể hiện củ a mảng b ằng cách sử dụ ng từ khóa new như sau: myIntArray = new int[6]; Khai b áo này sẽ thiết lập bên trong b ộ nhớ một mảng chứa sáu số nguyên. Ghi chú: dành cho lập trình viên Visual Basic, thành phần đầu tiên luôn bắt đầu 0, không có cách nào thiết lập cận trên và cận dưới củ a mảng, và chú ng ta cũng khô ng thể thiết lập lại kích thước củ a mảng. Điều quan trọng để p hân biệt giữa b ản thân mảng (tập hợp các thành phần) và các thành phần trong mảng. Đối tượng myIntArray là mộ t mảng, thành phần là năm số nguyên đ ược lưu giữ. Mảng trong ngô n ngữ C# là kiểu dữ liệu tham chiếu, đ ược tạo ra trên heap. Do đó myIntArray được cấp trên heap. Những thành phần củ a mảng đ ược cấp phát dựa trên các kiểu dữ liệu của chú ng. Số nguyên là kiểu dữ liệu giá trị, và do đó những thành phần củ a 214 Mảng, Chỉ Mục, và Tập Hợp
  15. Ngôn Ngữ Lập Trình C# m yIntArray là kiểu d ữ liệu giá trị, không phải số nguyên được boxing. Mộ t mảng củ a kiểu dữ liệu tham chiếu sẽ không chứa gì cả như ng tham chiếu đến những thành phần đ ược tạo ra trên heap. Giá trị mặc định Khi chúng ta tạo một mảng có kiểu d ữ liệu giá trị, mỗi thành phần sẽ chứa giá trị mặc định của kiểu d ữ liệu (xem b ảng 4.2, kiểu d ữ liệu và các giá trị mặc đ ịnh). Với khai b áo: myIntArray = new int[5]; sẽ tạo ra một mảng năm số nguyên, và mỗi thành phần được thiết lập giá trị mặc định là 0, đây cũng là giá trị mặc định của số nguyên. Khô ng giống với mảng kiểu dữ liệu giá trị, những kiểu tham chiếu trong mộ t mảng không được khở i tạo giá trị mặc đ ịnh. Thay vào đó, chúng sẽ đ ược khởi tạo giá trị null. Nếu chú ng ta cố truy cập đến một thành phần trong mảng kiểu dữ liệu tham chiếu trước khi chú ng đ ược khởi tạo giá trị xác định, chú ng ta sẽ tạo ra một ngoại lệ. Giả sử chúng ta tạo ra một lớp Button. Chú ng ta khai b áo một mảng các đố i tượng Button với cú p háp sau: Button[] myButtonArray; và chúng ta tạo thể hiện củ a mảng như sau: myButtonArray = new Button[3]; Ghi chú: chúng ta có thể viết ngắn gọn như sau: Button muButtonArray = new Button[3]; Khô ng giống với ví dụ mảng số nguyên trước, câu lệnh nà y không tao ra một mảng với những tham chiếu đến ba đối tượng Button. Thay vào đó việc nà y sẽ tạo ra mộ t mảng m yButtonArray với ba tham chiếu null. Để sử dụng mảng nà y, đ ầu tiên chúng ta phải tạo và gán đố i tượng Button cho từng thành phần tham chiếu trong mảng. Chú ng ta có thể tạo đố i tượng trong vòng lặp và sau đó gán từng đố i tượng vào trong mảng. Truy cập các thành phần trong mảng Để truy cập vào thành phần trong mảng ta có thể sử dụ ng to án tử chỉ mụ c ([]). Mảng d ùng cơ sở 0, do đó chỉ mục của thành phần đ ầu tiên trong mảng luôn luôn là 0 . Như ví dụ trước thành phần đầu tiên là myArray[0]. Như đã trình bày ở p hần trước, mảng là đối tượng, và do đó nó có những thu ộc tính. Mộ t trong những thu ộc tính hay sử dụng là Length, thuộ c tính nà y sẽ b áo cho biết số đối tượng trong một mảng. Một mảng có thể đ ược đ ánh chỉ mụ c từ 0 đến Length –1. Do đó nếu có năm thành phần trong mảng thì các chỉ mụ c là: 0, 1, 2, 3, 4. Ví dụ 9.1 minh họa việc sử dụ ng các khái niệm về mảng từ đ ầu chương tới giờ. Trong ví dụ một lớp tên là Tester tạo ra một mảng kiểu Employee và một mảng số nguyên. Tạo các đối tượng Employee sau đó in hai mảng ra màn hình. 215 Mảng, Chỉ Mục, và Tập Hợp
  16. Ngôn Ngữ Lập Trình C#  Ví dụ 9.1: làm việc với một mảng. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; // tạo một lớp đơn giản để l ưu trữ trong mảng public class Employee { // bộ khởi tạo l ấy một tham số public Employee( int empID ) { this.empID = empID; } public override string ToString() { return empID.ToString(); } // bi ến thành vi ên private private int empID; private int size; } public class Tester { static void Main() { int[] intArray; Employee[] empArray; intArray = new int[5]; empArray = new Employee[3]; // tạo đối tượng đưa vào mảng for( int i = 0; i < empArray.Length; i++) { empArray[i] = new Employee(i+5); } // xuất mảng nguyên for( int i = 0; i < intArray.Length; i++) { Console.Write(intArray[i].ToString()+”\t”); 216 Mảng, Chỉ Mục, và Tập Hợp
  17. Ngôn Ngữ Lập Trình C# } // xuất mảng Employee for( int i = 0; i < empArray.Length; i++) { Console.WriteLine(empArray[i].ToString()+”\t”); } } } } -----------------------------------------------------------------------------  Kết quả: 0 0 0 0 0 5 6 7 ----------------------------------------------------------------------------- Ví dụ bắt đ ầu với việc định nghĩa một lớp Employee, lớp nà y thực thi mộ t bộ khởi d ựng lấy một tham số nguyên. Phương thức ToString() đ ược kế thừa từ lớp Object được phủ quyết đ ể in ra giá trị empID củ a đố i tượng Employee. Các kiểu tạo ra là khai b áo rồ i mới tạo thể hiện của hai mảng. Mảng số nguyên được tự độ ng thiết lập giá trị 0 mặc định cho từng số nguyên trong mảng. Nội dung của mảng Employee được tạo bằng các lệnh trong vò ng lặp. Cuối cù ng, nội dung của cả hai mảng được xu ất ra màn hình console để đ ảm b ảo kết qu ả như mong muốn; năm giá trị đ ầu của mảng nguyên, ba số sau cù ng là của mảng Employee. Khởi tạo thành phầ n của mảng Chú ng ta có thể khởi tạo nội dung của một mảng ngay lúc tạo thể hiện củ a mảng b ằng cách đặt nhữ ng giá trị b ên trong dấu ngoặc ({}). C# cung cấp hai cú pháp đ ể khởi tạo các thành phần của mảng, một cú pháp d ài và một cú pháp ngắn: int[] myIntArray = new int[5] { 2, 4, 6, 8, 10}; int[] myIntArray = { 2, 4, 6, 8, 10}; Khô ng có sự khác biệt giữa hai cú p háp trên, và hầu hết các chươ ng trình đều sử dụ ng cú pháp ngắn hơ n do sự tự nhiên và lười đ ánh nhiều lệnh củ a người lập trình. Sử dụng từ khóa params Chú ng ta có thể tạo mộ t phương thức rồi sau đó hiển thị các số nguyên ra màn hình console b ằng cách truyền vào mộ t mảng các số nguyên và sử dụng vòng lặp foreach để duyệt qua từng thành phần trong mảng. Từ khóa params cho phép chú ng ta truyền một số biến của tham số mà không cần thiết phải tạo một mảng. Trong ví dụ kế tiếp, chúng ta sẽ tạo một phương thức tên DisplayVals(), phương thức nà y sẽ lấ y mộ t số các biến của tham số nguyên: public void DisplayVals( params int[] intVals) 217 Mảng, Chỉ Mục, và Tập Hợp
  18. Ngôn Ngữ Lập Trình C# Phương thức có thể xem mảng nà y như thể mộ t mảng được tạo ra tường minh và đ ược truyền vào tham số . Sau đó chú ng ta có thể tự do lặp lần lượt qua các thành phần trong mảng giố ng như thực hiện với b ất cứ mảng nguyên nào khác: foreach (int i in intVals) { Console.WriteLine(“DisplayVals: {0}”, i); } Tuy nhiên, phương thức gọi không cần thiết phải tạo tường minh mộ t mảng, nó chỉ đơn giản truyền vào các số nguyên, và trình biên d ịch sẽ kết hợp nhữ ng tham số nà y vào trong mộ t mảng cho phương thức DisplayVals, ta có thể gọ i phương thức như sau: t.DisplayVals(5,6,7,8); và chúng ta có thể tự do tạo một mảng đ ể truyền vào phương thức nếu muố n: int [] explicitArray = new int[5] {1,2,3,4,5}; t.DisplayArray(explicitArray); Ví dụ 9.3 cung cấp tất cả mã nguồ n để minh họa sử dụ ng cú p háp params.  Ví dụ 9.3: minh họa sử dụng params. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; public class Tester { static void Main() { Tester t = new Tester(); t.DisplayVals(5,6,7,8); int[] explicitArray = new int[5] {1,2,3,4,5}; t.DisplayVals(explicitArray); } public void DisplayVals( params int[] intVals) { foreach (int i in intVals) { Console.WriteLine(“DisplayVals {0}”, i); } } } } 218 Mảng, Chỉ Mục, và Tập Hợp
  19. Ngôn Ngữ Lập Trình C# -----------------------------------------------------------------------------  Kết quả: DisplayVals 5 DisplayVals 6 DisplayVals 7 DisplayVals 8 DisplayVals 1 DisplayVals 2 DisplayVals 3 DisplayVals 4 DisplayVals 5 ----------------------------------------------------------------------------- Câu lệnh lặp foreach Câu lệnh lặp foreach khá mới với nhữ ng người đ ã họ c ngôn ngữ C, từ khóa này đ ược sử dụng trong ngô n ngữ Visual Basic. Câu lệnh foreach cho phép chúng ta lặp qua tất cả các mục trong một mảng hay trong một tập hợp. Cú pháp sử dụ ng lệnh lặp foreach như sau: foreach ( in ) { // thực hi ện thông qua tương ứng với // từng mục trong mảng hay tập hợp } Do vậy, chúng ta có thể cải tiến ví dụ 9 .1 trước bằng cách thay việc sử dụ ng vòng lặp for bằng vòng lặp foreach để truy cập đến từng thành phần trong mảng.  Ví dụ 9.2: Sử dụng foreach. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; // tạo một lớp đơn giản để l ưu trữ trong mảng public class Employee { // bộ khởi tạo l ấy một tham số public Employee( int empID ) { this.empID = empID; } 219 Mảng, Chỉ Mục, và Tập Hợp
  20. Ngôn Ngữ Lập Trình C# public override string ToString() { return empID.ToString(); } // bi ến thành vi ên private private int empID; private int size; } public class Tester { static void Main() { int[] intArray; Employee[] empArray; intArray = new int[5]; empArray = new Employee[3]; // tạo đối tượng đưa vào mảng for( int i = 0; i < empArray.Length; i++) { empArray[i] = new Employee(i+10); } // xuất mảng nguyên foreach (int i in intArray) { Console.Write(i.ToString()+”\t”); } // xuất mảng Employee foreach ( Employee e in empArray) { Console.WriteLine(e.ToString()+”\t”); } } } } ----------------------------------------------------------------------------- Kết qu ả của ví dụ 9 .2 cũ ng tương tự như ví dụ 9.1. Tuy nhiên, với việc sử dụ ng vòng lặp for ta phải xác đ ịnh kích thước củ a mảng, sử dụng biến đ ếm tạm thời để truy cập đến từng thành phần trong mảng: 220 Mảng, Chỉ Mục, và Tập Hợp
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
3=>0