2.1 Mối quan hệ giữa C# và .NET C# là một ngơn ngữ lập trình mới, và được biết đến với hai lời chào: Nĩ được thiết kế riêng để dùng cho Microsoft's .NET Framework Một nền khá mạnh cho
Trang 1Learning CSharp
Trang 2Table of Contents
1 Bảng nội dung 5
2 Chương 1:Kiến trúc C# và NET 5
2.1 Mối quan hệ giữa C# và NET 6
2.2 The Common Language Runtime 6
2.3 Assemblies 10
2.4 Tìm hiểu về Intermediate Language 12
2.5 Các lớp của NET Framework 21
2.6 Tạo ra các ứng dụng NET bằng C# 22
2.7 Vai trò của C# trong kiến trúc NET Enterprise 26
2.8 Tóm tắt 27
3 Chương 2: Căn bản về C# 28
3.1 Trước khi bắt đầu 29
3.2 Chương trình C# đầu tiên 29
3.3 Biến 30
3.4 Kiểu dữ liệu tiền định nghĩa 33
3.5 Câu lệnh điều kiện 36
3.6 Cấu trúc chương trình 41
3.7 Phương thức 43
3.8 Mảng 46
3.9 Toán tử 48
3.10 An toàn kiểu 51
3.11 Kiểu lệt kê 52
3.12 Namespaces 54
3.13 Phương thức Main() 56
3.14 Các tập tin biên dịch của C# 57
3.15 Console I/O 58
3.16 Cách dùng chú giải 59
3.17 Từ định danh và từ khóa 59
3.18 Tóm tắt 60
4 Chương 3: Hướng đối tượng trong C# 60
4.1 Lớp và thừa kế 61
4.2 Thuộc tính 65
Trang 34.3 Lớp đối tượng 67
4.4 Interfaces 69
4.5 Construction and Disposal 74
4.6 Các trường chỉ đọc 83
4.7 Structs 84
4.8 Nạp chồng toán hạng 86
4.9 Bộ lập chỉ mục 92
4.10 Tóm tắt 94
5 Chương 4 : Các chủ đề tiến bộ trong C# 95
5.1 Lỗi và xử lí biệt lệ 95
5.2 Ép kiểu do người dùng định nghĩa 113
5.3 Delegates 122
5.4 Các sự kiện 132
5.5 Chỉ thị tiền xử lí trong C# 139
5.6 Attributes 141
5.7 Quản lí bộ nhớ dưới nền C# 144
5.8 Mã không an toàn 148
5.9 Tóm tắt 161
6 Chương 5 : C# và các lớp cơ sở 161
6.1 System.Object 162
6.2 Xử lí chuỗi 165
6.3 Regular Expressions 175
6.4 Nhóm các đối tượng 182
6.5 Attributes tùy chọn 195
6.6 Reflection 201
6.7 Luồng 210
6.8 Tóm tắt 220
7 Chương 6: Lập trình trong mội trường NET 221
7.1 Visual Studio NET 221
7.2 Những công cụ khác của NET 243
7.3 Nguyên tắc sử dụng NET 244
7.4 Tóm tắt 247
8 Chương 7: Các ứng dụng Window 247
8.1 Windows Applications in NET 248
Trang 48.2 Windows Forms 250
8.3 Windows Controls 276
8.4 Custom Controls 279
8.5 Tóm tắt 282
9 Chapter 8: Assemblies 282
9.1 Assemblies là gì ? 283
9.2 Cấu trúc của Assembly 286
9.3 Hổ trợ xuyên ngôn ngữ 293
9.4 Thêm các tài nguyên đến Assembly 297
9.5 Global Assembly Cache 301
9.6 Tạo ra các Shared Assembly 303
9.7 Cấu hình 309
9.8 Triển khai 310
9.9 Tóm tắt 312
10 Chương 9: Truy xuất dữ liệu với NET 313
10.1 Tổng quan về ADO.NET 313
10.2 Sử dụng các Database Connection 315
10.3 Commands 320
10.4 Truy cập nhanh cơ sở dữ liệu với Data Reader 327
10.5 Quản lí dữ liệu và các mối quan hệ: The DataSet 330
10.6 Các sơ đồ XML 341
10.7 Tạo một DataSet 347
10.8 Các cố gắng thay đổi DataSet 349
10.9 Làm việc với ADO.NET 353
10.10 Tóm tắt 358
11 Chương 10 : Cách xem dữ liệu trong NET 359
11.1 The DataGrid Control 360
11.2 Gắn kết dữ liệu 372
11.3 Visual Studio and Data Access 378
11.4 Tóm tắt 397
12 Chương 11: Thao tác trên XML 398
12.1 Các hổ trợ XML chuẩn trong NET 398
12.2 Giới thiệu khônggian tên System.Xml 399
12.3 sử dụng MSXML trong NET 400
Trang 512.4 Sử dụng các lớp trong System.Xml 403
12.5 Đọc và ghi Streamed XML 404
12.6 Sử dụng DOM trong NET 413
12.7 Sử dụng XPath và XSLT trong NET 419
12.8 XML và ADO.NET 428
12.9 Tóm tắt 440
13 Chapter 12: File and Registry Operations 440
13.1 Quản lí tập tin hệ thống 441
13.2 Di chuyển,sao chép và xoá các tập tin 447
13.3 Đọc và ghi tập tin 451
13.4 Đọc và ghi đến Registry 457
13.5 Tóm tắt 461
14 Chương 13: Làm việc với Active Directory 461
14.1 Kiến trúc của Active Directory 462
14.2 Các công cụ quản trị cho Active Directory 468
14.3 Active Directory Service Interfaces (ADSI) 471
14.4 Lập trình với Active Directory 472
14.5 Tìm kiếm các đối tượng người dùng 485
14.6 Tóm tắt 490
15 Addenda 491
15.1 Các hỗ trợ XML chuẩn trong 491
Trang 61 Bảng nội dung
Lập trình với C#
Chương 1 (See 2.) - Kiến trúc của C# và NET
Chương (See 3.) 2 (See 3.) - Căn bản C#
Chương (See 4.) 3 (See 4.)
-(See 4.) Hướng đối tượng trong C#
Chương (See 5.) 4 (See 5.) - Những chủ đề tiến bộ trong C#
Chương (See 6.) 5 (See 6.) - C# và các lớp cơ sở
Chương (See 7.) 6 (See 7.) - Lập trình trong mơi trường NET
Chương (See 8.) 7 (See 8.) - Windows Applications
Chương (See 9.) 8 (See 9.) - Assemblies
Chương (See 10.) 9 (See 10.) - Truy cập cơ sở dữ liệu với NET
Chương (See 11.) 10 (See 11.) - Viewing NET Data
Chương (See 12.) 11 (See 12.) - Thao tác XML
Chương (See 13.) 12 (See 13.) - File and Registry Operations
Chương (See 14.) 13 (See 14.) - Làm việc với Active Directory
Biên dịch từ cuốn Professional C#, 2nd Edition, Xuất bản bởi Wrox Press Ltd
2 Chương 1:Kiến trúc C# và NET
Trang 7 Cấu trúc và các lập luận C# được phản ánh các phương pháp luận của NET ngầm bên dưới
Trong nhiều trường hợp, các đặc trưng của C# thậm chí được quyết định dựa vào các đặc trưng của NET, hoặc thư viện lớp cơ sở của NET
Chính bởi tầm quan trọng của NET, nên các bạn cần phải biết sơ qua về NET trước khi đi vào ngơn ngữ C# Đây cũng chính là mục đích của chương này
Chúng ta sẽ tìm hiểu xem chuyện gì sẽ xảy ra khi mã của các ngơn ngữ hướng NET (bao gồm C#) được biên dịch và thực thi Đây là một lĩnh vực rộng, chúng ta sẽ tìm hiểu kĩ hơn về
Microsoft Intermediate Language (MS-IL), ngơn ngữ trung gian trong NET mã của các
ngơn ngữ khác đều phải được biên dịch về ngơn ngữ này trước khi thực thi Cụ thể chúng ta
sẽ tìm hiểu xem cách thức mà MS-IL với phần dùng chung Common Type System (CTS) và
Common Language Specification (CLS) cĩ thể cung cấp cho chúng ta sự tương hoạt giữa
các ngơn ngữ hướng NET Chúng ta cũng sẽ trình bày các ngơn ngữ biết NET khác bao gồm
VB và C++
Sau đĩ chúng ta sẽ xem xét các đặc trưng khác của NET, bao gồm các assembly, các
namespace, và thư viện lớp cơ bản của NET Chúng ta sẽ kết thúc chương này bằng việc liệt
kê vắn tắt về các loại ứng dụng mà chúng ta cĩ thể tạo ra trong C#
2.1 Mối quan hệ giữa C# và NET
C# là một ngơn ngữ lập trình mới, và được biết đến với hai lời chào:
Nĩ được thiết kế riêng để dùng cho Microsoft's NET Framework (Một nền khá mạnh cho sự phát triển, triển khai, hiện thực và phân phối các ứng dụng)
Nĩ là một ngơn ngữ hồn tồn hướng đối tượng được thiết kế dựa trên kinh nghiệm của các ngơn ngữ hướng đối tượng khác
Một điều quan trọng cần nhớ C# là một ngơn ngữ độc lập Nĩ được thiết kế để cĩ thể sinh ra
mã đích trong mơi trường NET, nĩ khơng phải là một phần của NET bởi vậy cĩ một vài đặc trưng được hỗ trợ bởi NET nhưng C# khơng hỗ trợ và bạn cũng đừng ngạc nhiên khi cĩ những đặc trưng C# hỗ trợ mà NET khơng hỗ trợ (chẳng hạn như quá tải tốn tử)
Để tạo được những ứng dụng mang tính hiệu quả cao, chúng ta sẽ xem qua về hoạt động của NET
2.2 The Common Language Runtime
Trung tâm của NET framework là mơi trường thời gian chạy, gọi là Common Language
Runtime (CLR) hoặc NET runtime Mã của các điều khiển trong CLR thường là mã cĩ
quản
Tuy nhiêu, trước khi được thực thi bởi CLR, mã được phát triển trong C# (hoặc các ngơn ngữ khác) cần phải được biên dịch.Quá trình biên dịch trong NET xảy ra theo hai bước:
Trang 81 Dịch mã nguồn thành Microsoft Intermediate Language (MS-IL)
2 Dịch IL thành mã nền cụ thể bởi CLR
Mới nhìn có vẻ hơi dài dòng Nhưng thật sự, một tiến trình dịch hai mức là rất cần thiết, bởi vì trạng thái của Microsoft Intermediate Language (mã có quản) là chìa khóa cung cấp nhiều lợi ích trong NET
Các lợi ích của mã có quản
Microsoft Intermediate Language (thường được viết tắt là"Intermediate Language", hay "IL") tương tự như ý tưởng về mã Java byte, nó là một ngôn ngữ cấp thấp với những cú pháp đơn giản (dựa trên cơ sở mã số hơn là text), chính điều này sẽ làm cho quá trình dịch sang mã máy nhanh hơn Hiểu kĩ các cú pháp này sẽ mang lại những lợi ích đáng kể
Độc lập nền
Trước tiên, nó có nghĩa là các file chứa mã lệnh có thể chạy trên bất kì nền nào, vào thời gian chạy trình biên dịch cuối sẽ hoạt động và mã có thể chạy trên một nền cụ thể Nói cách khác việc dịch mã nguồn sang Intermediate Language cho phép độc lập nền trong NET, nó giống như cách dịch mã nguồn sang Java byte code cung cấp sự độc lập nền trong Java
Bạn cũng nên biết rằng sự độc lập nền của NET chỉ là trên lí thuyết bởi vì tại thời điểm này, NET chỉ có sẵn trong Windows Tuy nhiên việc chuyển NET sang những nền khác đang được khảo sát tỉ mỉ (xem ví dụ Mono project, một sự cố gắng tạo một thực thi mã nguồn mở trong NET, tại địa chỉ http://www.go-mono.com/)
Sự cải tiến trong thực thi
Mặc dù chúng ta đã so sánh với Jave, IL thật sự có một chút khả quan hơn Java IL luôn là
trình biên dịch Just-In-Time, ngược lại Java byte code thì thường là thông dịch Một trong
những bất lợi của Java là vào lúc thực thi quá trình dịch từ java byte code sang mã máy tốn nhiều tài nguyên
Thay vì phải dịch toàn bộ ứng dụng một lần, trình biên dịch JIT sẽ biên dịch từng phần mã khi
nó được gọi Khi mã được dịch rồi, mã kết quả sẽ được giữ lại cho tới khi thoát khỏi ứng dụng, chính vì thế nó không phải biên dịch lại trong lần chạy kế tiếp Microsoft quả quyết rằng cách xử lí này có hiệu lực cao hơn là dịch toàn bộ ứng dụng, bởi vì có trường hợp một khối lượng lớn mã của ứng dụng không bao giờ được sử dụng trong thời gian chạy Khi sử dụng trình biên dịch JIT , các đoạn mã này sẽ không bao giờ được dịch
Chính vì thế chúng ta hi vọng rằng mã IL sẽ thực thi nhanh như là mã máy Microsof cam kết chúng ta sẽ có một thay đổi lớn trong thực thi Lời lí giải là, là lần dịch cuối cùng trong thời gian chạy, trình biên dịch JIT sẽ biết chính xác loại vi xử lí mà chương trình sẽ chạy Có nghĩa là nó có thể tối ưu mã thi hành cuối cùng bằng cách tham chiếu đến các đặc trưng của từng các bộ lệnh ứng với các loại vi xử lí đó
Các trình biên dịch truyền thống đều có tối ưu mã, nhưng chúng chỉ có thể tối ưu độc lập không quan tâm đến loại vi xử lý mà chương trình sẽ chạy Bởi vì trình biên dịch truyền thống biên dịch toàn bộ ứng dụng sang mã máy trước khi thực thi Có nghĩa là trình biên dịch không
Trang 9hề biết loại vi xử lí mà chương trình sẽ được chạy, chẳng hạn nó có thể là một vi xử lí tương thích x86 hoặc một vi xử lí Alpha Visual Studio 6, tối ưu cho cho một máy tương thích Pentium, bởi vậy mã mà nó sinh ra không đem lại lợi ích gì đối với các đặc trưng phần cứng của vi xử lí Pentium III Trong khi đó, trình biên dịch JIT có thể thực hiện tối ưu giống như Visual Studio 6, ngoài ra nó còn có thể tối ưu cho các loại vi xử lí cụ thể mà mã chương trình
sẽ chạy
Tương hoạt giữa các ngôn ngữ
Chúng ta đã biết cách thức IL cho phép độc lập nền, trình biên dịch JIT có thể cải thiện quá trình thực thi Tuy nhiên, IL cũng làm cho tương hoạt giữa các ngôn ngữ trở nên dễ dàng hơn Bạn có thể biên dịch IL từ một ngôn, và mã này sau đó có thể tương hoạt với IL được biên dịch bởi một ngôn ngữ khác
Bây giờ chắc bạn đang tự hỏi rằng những ngôn ngữ nào có thể tương tác với C# trong NET, hãy xem qua các ngôn ngữ biết NET phổ biến sau
VB.NET
Visual Basic đã được tân trang lại để có thể tương thích với công nghệ NET Từ việc phát triển Visual Basic trong những năm gần đây cho thấy rằng trong các phiên bản trước, Visual Basic 6, nó không tương thích với lập trình NET Ví dụ, nó đặt nặng vấn đề tích hợp COM,
và nó chỉ đưa ra các sự kiện để phát triển, hầu hết mã nền không có sẵn trong mã nguồn Không những thế, nó không thực sự hỗ trợ tính thừa kế và các kiểu dữ liệu chuẩn của Visual Basic không tương thích với NET
Visual Basic đang được hoàn thiện trong Visual Basic NET, cũng đừng ngạc nhiên khi sự thay đổi này xảy ra trên một diện rộng Về phương diện thực hành bạn có thể xem VB.NET như là một ngôn ngữ mới Mã VB 6 không không thể được biên dịch trong như mã VB.NET
Sự chuyển đổi từ lập trình VB 6 sang VB.NET yêu cầu một sự thay đổi lớn về mã Tuy nhiên hầu hết các sự thay đổi này có thể được thực hiện một cách tự động bởi Visual Studio NET (sự cải tiến của VS cho việc sử dụng NET) Nếu bạn cố gắng đọc một đề án VB 6 trong Visual Studio NET, nó sẽ cải tiến đề án của bạn, có nghĩa là nó sẽ viết lại mã nguồn VB 6 thành mã nguồn VB.NET Điều đó có nghĩa là việc này sẽ gặp rắc rối khi bạn cắt ngang, bạn
sẽ phải kiểm tra lại mã VB.NET mới để chắc rằng đề án của bạn vẫn chạy đúng
Một hiệu ứng phụ là không còn khả năng biên dịch NET sang mã thực thi VB.NET chỉ biên dịch sang IL, giống như C# Nếu như bạn muốn tiếp tục mã hóa trong VB 6, bạn có thể làm như vậy, nhưng khi mã thực thi quá dài nó sẽ lờ đi NET Framework, và bạn cần phải giữ lại Visual Studio 6 đã cài đồng thời phải hoàn toàn tin vào môi trường phát triển trong Visual Studio
Managed C++
Vào lúc đó trong Visual C++ 6, C++ đã có một khối lượng lớn các mở rộng của Microsoft trong Windows Với Visual C++ NET, các mở rộng này được tăng thêm cho việc hỗ trợ NET framework Có nghĩa là mã nguồn C++ sẽ vẫn tiếp tục được dịch sang mã máy không
có gì khác biệt Cũng có nghĩa là nó sẽ chạy độc lập trong môi trường NET Nếu bạn không
Trang 10muốn mã C++ của bạn chạy trong môi trường NET Framework, bạn có thể đơn giãn đặt dòng lệnh sau vào đầu mã nguồn của bạn:
#using <mscorlib.dll>
Bạn cũng có thể bỏ qua cờ /clr trong trình biên dịch, cờ này cho biết rằng bạn muốn biên dịch sang mã có quản, và nó sẽ phát ra IL thay vì mã máy Có một điều thú vị trong C++ khi bạn biên dịch sang mã có quản, trình biên dịch có thể phát ra các IL có nhúng các mã máy Điều này có nghĩa là bạn có thể pha trộn kiểu có quản và kiểu không quản trong mã C++ Bằng cách mã C++:
mã có quản C++ bỏ qua tương thích COM
Trình biên dịch sẽ phát ra một lỗi nếu bạn cố gắng dùng những đặc trưng mà mã có quản của NET không hỗ trợ trong (ví dụ, khuôn mẫu hay đa thừa kế) Bạn cũng sẽ nhận ra rằng bạn sẽ phải dùng các đặc trưng không thuần C++ (chẳng hạn từ khoá gc trong ví dụ trên) khi sử dụng các lớp có quản
Bởi vì trong VC++ cho phép giải phóng bộ nhớ thủ công dưới dạng một con trỏ, trình biên dịch C++ không thể phát ra mã cho kiểu bộ nhớ an toàn CLR Nếu ứng dụng của bạn thật sự cần phải nhận dạng kiểu bộ nhớ an toàn CLR, bạn cần phải viết mã nguồn trong các ngôn ngữ khác (như C# hay VB.NET)
J++ and J#
J++ vẫn được hỗ trợ cho chỉ vì mục đích tương thích trước đây Microsoft không còn phát triển bất kì nền tảng nào hỗ trợ việc biện dịch sang máy Java ảo Thay vì đó, Microsoft phát
triển hai công nghệ tách biệt Java/J++ phát triển bên dưới ngọn cờ JUMP (Java User
Migration Path) và "JUMP trong NET"
Công nghệ đầu tiên là Visual J# Về bản chất nó được thêm vào Visual Studio.NET để cho phép bạn viết và biên dịch mã J++ Sự khác biệt đó là thay vì biên dịch sang một Java Virtual Machine, J# sẽ biên dịch sang IL, vì vậy nó sẽ hoạt động như là một ngôn ngữ của NET Ngừơi dùng J# sẽ có thể được hưởng các thuận lợi của các đặc tính của VS.NET Microsoft tin răng người dùng J++ sẽ nhanh chóng nhận ra điều đó nếu họ thích làm việc trong với NET
Sự lựa chọn thứ hai là công cụ tự động hỗ trợ việc chuyển mã J++ sang mã C# Sự giống nhau giữa J++ và C# làm cho việc chuyển đổi này trở nên dễ dàng hơn
Trang 11Không giống như J# cũng không như các công cụ chuyển đổi ngôn ngữ có sẵn như là một phần của NET hay trong Visual Studio NET, thay vì thế nó được cung cấp riêng Để biết thêm thông tin liên hệ http://msdn.microsoft.com/visualj/.
COM and COM+
COM và COM+ không là công nghệ chính của NET, bởi vì các thành phần cơ bản của chúng không thể dịch sang IL (mặc dù vẫn có thể làm điều đó khi tổ chức thành phần COM bằng mã C++) Tuy nhiên COM+ vẫn còn là một công cụ quan trọng, từ khi đặc tính của nó được nhân lên trong NET Ngoài ra, thành phần COM vẫn còn làm việc và NET kết hợp chặc chẽ các đặc trưng tương hoạt COM để mã có quản có thể gọi đến COM và ngược lại (sẽ được bàn thêm ở chương 17)
2.3 Assemblies
Một assembly là một đơn vị luận lí chứa mã đã được biên dịch sang NET Chúng ta sẽ bàn kĩ
về các assemblie trong chương 8, ở đây chúng ta sẽ nói sơ về nó
Một assembly là một tự mô tả đầy đủ, và nó giống một đơn vị luận lí hơn là một đơn vị vật lí, điều đó có nghĩa là nó có thể chứa trong nhiều file (thật vậy các assemblie động được lưu trong bộ nhớ không phải trong file) Nếu một assembly được lưu trong nhiều file, thì sẽ có một file chính chứa các con trỏ và các mô tả về các file khác của assembly
Chú ý rằng, câu trúc assembly được dùng chung cho cả mã thi hành và mã thư viện Sự khác biệt duy nhất là assembly thi hành chứa lối vào chương trình chính trong khi assembly thư viện thì không có
Một điểm quan trọng trong các assembly là chúng chứa metadata dùng để mô tả các kiểu và phương thức được định nghĩa trong mã tương ứng Một assembly, tất nhiên cũng chứ
assembly metadata dùng để mô tả chính assembly đó Assembly metadata này, chứa một vùng
đựơc hiểu như là manifest, cho phép kiểm tra phiên bản và tình trạng của assembly
ildasm, một tiện ích có sẵn của Windows, có thể dùng để nghiên cứu nội dung của một
assembly, bao gồm manifest metadata Chúng ta sẽ lấy vi dụ về ildasm trong chương 8
Thật vậy một assembly chứa metadata của chương trình nghĩa là các ứng dụng hoặc các assembly khác có thể gọi mã trong môt assembly mà không cần tham chiếu đến Registry,
Trang 12hoặc một dữ liệu nguồn khác, Một điểm quan trọng trong cách làm của COM cũ, các GUID của các thành phần và giao diện interfaces không thể đạt được từ Registry
Việc dàn trải dự liệu thành 3 định vị khác nhau đồng nghĩa với việc tạo ra mối nguy hiểm trong đồng bộ hoá, nó ngăn không cho các thành phần khác sử dụng Với assemblies, sẽ không còn những mối nguy hiểm như vậy, bởi vì tất các các metadata được lưu trong bộ lệnh thi hành của chương trình Chú ý rằng dù cho các assemblie được lưu thành một vài file, chúng vẫn không gây vấn đề gì về đồng bộ hoá dữ liệu Đó là vì nhờ vào file assembly chính, file này chứa đường dẫn, các thông tin chi tiết, mã băm, và nội dung của các file khác, điều đó
có nghĩa là nếu một file bị thay thế, hay bị phá hoại, nó sẽ được tìm ra và sẽ không cho load
Assemblies bao gồm 2 loại: các shared và private assembly
Private Assemblies
Private assemblies là kiểu đơn giản nhất Nó chứa phần mềm và chỉ được dùng cho phần mềm
đó Với phần mô tả này bạn có thể chứa đựng các private assemblie hòng cung cấp cho một ứng dụng kiểu thực thi và một số thư viện, các thư viện này chứa mã sẽ được thi hành bởi ứng dụng đó
Hệ thống đảm bảo rằng private assemblies sẽ không được dùng bởi phần mềm khác, bởi vì một ứng dụng chỉ có thể load private assemblies trong cùng folder với chương trình chính hoặc là trong một thư mục con của nó
Chúng ta không thể tin cậy rằng tất cả các phần mềm luôn được cài đặt trong thư mục của nó, nghĩa là sẽ không bao giờ có chuyện một gói phần mềm ghi đè, sửa chữa hoặc vô tình load một private assemblies dành riền cho một gói khác Vậy làm sao để các Private assemblie chỉ được dùng bởi gói phần mềm mà nó mô tả? Cần có một cơ chế bảo vệ, sao cho khi một sản phẩm thương mại khác cài đè lên một phiên bản assembly mới (chưa kể đến các chương trình đựơc thiết kế để phá hoại), thì sẽ không có chuyện tranh chấp tên Nếu có sự trùng tên trong các assembly, đều đó không quan trọng và các ứng dụng chỉ có thể nhìn thấy một bộ các assembly
Bởi vì một private assembly là một tự định nghĩa trọn vẹn, tiến trình xử lí cực kì đơn giản Bạn đơn giản thay thế các file thích hợp vào thư mục thíhc hợp trong file hệ thống (Không
cần phải đăng kí trong registry) Tiến trình này được gọi là zero impact (xcopy) installation
Shared Assemblies
Shared assemblies được dành cho cácc thư viện công cộng có thể dùng cho bất kì ứng dụng nào Bởi vì bất kì ứng dụng nào cũng có thể truy xuất một shared assembly, cần phải có các
cơ chế để bảo vệ các rủi ro sau:
Tranh chấp tên, khi một công ty tạo ra các shared assembly trùng tên với các shared assembly sẵn có của bạn Về mặt lí thuyết mã của bạn có thể truy xuất vào cả hai assembly này song đây có thể là một vấn đề phức tạp
Lỗi của một assembly có thể bị ghi đè bởi một phiên bản khác của cùng same
assembly - một phiên bản mới không tương thích với những gì sẵn có
Trang 13Giải pháp cho những vấn đề trên là đặt các shared assembly trong một cây thư mục đặt biệt
của hệ thống, có thể xem như là assembly cache toàn cục Không giống như các private
assembly, nó không đơn giản là copy assembly sang một thư mục thích hợp - nó cần được cài đặt rõ ràng vào cache Tiến trình này có thể được thực thi bởi một số tiện ích của NET, bao gồm luôn quá trình kiểm tra trên assembly, tương tự như cài đặt một thư mục trong assembly cache để đảm bảo tính toàn vẹn của assembly
Để tránh tranh chấp tên, shared assemblies đưa ra một được quản lí dựa trên một khóa mật mã
chính Tên này được gọi là strong name, được bảo đảm về tính độc nhất, và phải được trích
dẫn bởi ứng dụng muốn tham chiếu đến một shared assembly
Vấn đề về tương thích với lỗi do ghi đè một assembly được đánh địa chỉ theo thông tín phiên bản trong assembly manifest, và cho phép cài đặt song song
2.4 Tìm hieåu veà Intermediate Language
Như chúng ta đã biết, Intermediate Language hoạt động như là bản chất của NET
Framework Là lập trình viên C#, chúng ta nên biết rằng mã C# sẽ luôn được dịch sang
Intermediate Language trước khi nó được thực thi (thật vậy, trình biên dịch C# chỉ dịch sang
mã có quản) Chúng ta hãy cùng khám phá các tính năng chính của IL, bất kì ngôn ngữ nào hướng NET cũng sẽ hỗ trợ các đặc tính chính của IL
Sau đây là những đặc tính chính của Intermediate Language:
Hướng đối tượng và dùng interfaces
Sự tách biệt giữa kiểu giá trị và kiểu tham chiếu
Định kiểu mạnh
Quản lỗi thông qua các ngoại lệ
Sự dụng các thuộc tính
Bây giờ chúng ta sẽ cùng khám phá các đặc tính trên
Hỗ trợ hướng đối tượng và dùng giao diện
Ngôn ngữ độc lập nền của NET có một vài giới hạn riêng Cụ thể trong lúc thực thi IL chắc chắn sẽ thực thi một cách thức lập trình riêng, và các ngôn ngữ khác phải chú ý đến việc tương thích với cách thức lập trình này IL đã được Microsoft phát triển như là một ngôn ngữ hướng đối tượng cổ điển hỗ trợ đầy đủ thừa kế đơn giữa các lớp
Trang 14Bên cạnh lập trình hướng đối tượng đơn, Intermediate Language còn nêu ra ý tưởng về
interfaces (giao diện), cái đã được tích hợp trong Windows với giao diện COM .NET nó không giống như giao diện COM; chúng không cần phải hỗ trợ bất kì một kiến trúc COM nào (ví dụ, chúng không xuất phát từ IUnknown, và chúng cũng không liên quan gì đến các
GUID) Tuy nhiên chúng có thể dùng chung các giao diện COM
Hướng đối tượng và thực thi chéo ngôn ngữ
Bây chúng ta sẽ tìm hiểu về hoạt động của NET nghĩa là hoạt động biên dịch sang mã
Intermediate Language, điều đó nói lên rằng bạn cần phải lập trình theo cách thức hướng đối tượng truyền thống Không những thế chúng còn cung cấp cho chúng ta khả năng chuyển giao ngôn ngữ Sau cùng, C++ và Java cả hai đều dùng những biến thể của hướng đối tượng, dù vậy chúng vẫn còn được quan tâm để có thể thực thi chéo Chúng ta cần tìm hiểu một chút về thực thi chéo ngôn ngữ
Trước tiên chúng ta cần hiểu chính xác thực thi ngôn ngữ chéo là gì Sau cùng, COM cho phép các thành phần được viết bởi các ngôn ngữ khác nhau có thể thực thi chéo COM, là một nhị phân chuẩn, cho phép các thành phần có thể hiểu nhau và có thể gọi các phương thức cũng như thuộc tính lẫn nhau mà không cần quan tâm đến ngôn ngữ đã tạo ra chúng Để làm được điều đó mỗi đối tượng phải có khả năng giao tiếp với thời gian chạy của COM, và phải
có khả năng truy cập thông qua một giao diện Các thành phần chỉ có thể giao tiếp với nhau trong thời gian chạy COM Dù rằng các thành phần của COM có thể giao tiếp với nhau bất chấp ngôn ngữ đã tạo ra chúng, tuy nhiên COM không hỗ trợ hoạt động thừa kế, chính vì thế
nó đã đánh mất các thuận lợi của lập trình hướng đối tượng
Một vấn đề xảy ra khi bẫy lỗi là các thành thành phần phải được bẫy lỗi trong ngôn ngữ đã tạo chúng, và bạn không thể bẫy lỗi từng bước trên các ngôn ngữ khác nhau Vậy thực thi chéo ngôn ngữ được hiểu như là các lớp được tạo ra trong một ngôn ngữ có thể giao tiếp lẫn nhau với các lớp được tạo ra trong các ngôn ngữ khác Cụ thể là:
Một lớp được tạo ra trong một ngôn ngữ có thể thừa kế từ một lớp được viết trong một ngôn ngữ khác
Một lớp có thể chứa thể hiện của một lớp khác không quan tâm đến ngôn ngữ đã tạo ra hai lớp đó
Một đối tượng có thể gọi trực tiếp phương thức của một đối tượng khác được viết bởi một ngôn ngữ khác
Các đối tượng (hoặc các tham chiếu đến các đối tượng) có thể được truyền qua lại giữa các hàm
Bạn có khả năng bẫy lỗi từng bước chương trình nguồn giữa các ngôn khác nhau
Thật bất ngờ về những gì mà NET và thực thi ngôn ngữ chéo đã làm được Tiện ích bẫy lỗi từng được giới thiệu như là khả năng của Visual Studio NET IDE hơn là CLR
Sự khác biệt giữa kiểu dữ liệu giá trị và kiểu dữ liệu tham chiếu
Như bất kì ngôn ngữ lập trình nào, IL cung cấp một số tiền định nghĩa về các kiểu dữ liệu nguyên thủy Một đặc trưng của Intermediate Language là phân biệt rạch ròi giữa kiểu dữ liệu
giá trị và kiểu dữ liệu tham chiếu Kiểu giá trị là các biến được dùng để lưu trực tiếp giá trị, trong khi đó kiểu tham chiếu là các biến chứa địa chỉ của dữ liệu
Trang 15Trong C++, kiểu tham chiếu có thể coi như là một con trỏ, trong khi đó ở Visual Basic, kiểu tham chiếu có thể coi là các đối tượng, trong VB 6 luôn truy cập thông qua tham chiếu Intermediate Language cũng chỉ rõ về cách thức lưu trữ dữ liệu: ví như một kiểu tham chiếu
luôn được lưu trong vùng managed heap của bộ nhớ, trong khi đó kiểu giá trị lại được lưu trong stack (tuy nhiên nếu kiểu dữ liệu được khai báo là một trường của kiểu tham chiếu,
chúng vẫn được lưu ở heap) Chúng ta sẽ bàn về stack và heap trong chương 3
Định kiểu mạnh
Một điểm mạnh trong IL là định kiểu mạnh Nghĩa là tất cả các biếu đều được đánh dấu rõ ràng và chuyên biệt về kiểu dữ liệu (IL không còn hỗ trợ kiễu Variant cho Visual Basic và ngôn ngữ kịch bản) Cụ thể là IL không cho phép các hoạt động trả về các kiểu dữ liệu không
rõ ràng
Trong trường hợp là người phát triển VB có lẽ bạn sẽ rất lo lắng về kiểu, bởi vì khi dùng kiểu
dữ liệu Variant VB tự động ép kiểu giúp bạn Còn là người phát triển C++, có lẽ bạn sẽ dùng các casting pointer giữa các kiểu Lập trình theo cách này có thể là một lập trình mạnh, tuy nhiên nó phá vỡ tính an toàn kiểu Từ bây giờ, nó chỉ còn hỗ trợ trong những trường hợp đặc biệt trong một số ngôn ngữ có khả năng biên dịch sang mã có quản Thật vậy, các con trỏ (không phải là tham chiếu) chỉ còn cho phép trong các khối mã đặc biệt trong C#, trong VB không có (mặc dù nó cho phép trong C++) Nếu dùng con trỏ trong mã nguồn nó sẽ không chuyển thành mã có quản và sẽ không được kiểm tra bởi CLR
Bạn cũng nên biết rằng trong một số ngôn ngữ biết NET, chẳng hạn như VB.NET, vẫn cho phép mơ hồ kiểu, tuy nhiên chỉ để có thể làm được như thể làm được như vậy thì trình biên dịch đã xác định kiểu bảo vệ kiểu trước khi phát ra IL
Mặc dù, kiểu bảo vệ lúc đầu có thể sinh ra nhiều cản trở trong lập trình nhưng trong nhiều trường hợp kiểu bảo vệ sẽ mang lại nhiều lợi ích to lớn trong các dịch vụ được cung cấp bởi NET Chẳng hạn các dịch vụ sau:
Tầm quan trọng của Strong Data Typing đối với Language Interoperability
Một khía cạnh quan trong của strong data typing là nếu một lớp xuất thân hoặc chứa một lớp
khác thì nó cần phải biết tất cả các kiểu dùng trong các lớp đó Thật vậy, nó đã từng các chướng ngại lớn trong việc thực thi ngôn ngữ chéo ở các hệ thống không hỗ trợ trước đấy Thông tin này không có sẵn trong các file thi hành và DLL chuẩn
Giả sử rằng một phương thức trong VB.NET được định nghĩa là sẽ trả về một Integer, một trong những kiểu dữ liệu chuẩn của VB.NET C# không có kiểu dữ liệu có tên như vậy Chúng ta chỉ có thể dùng phương thức này để trả về một kiểu của C# nết trình biên dịch biết
Trang 16cách ánh xạ kiểu VB.NET's Integer đến một trong những kiểu được định nghĩa trong C# Vậy NET đã làm việc đó như thế nào?
Common Type System (CTS)
Vấn đề về kiểu dữ liệu này được NET giải quyết bằng cách dùng Common Type System (CTS) CTS định nghĩa các kiểu dữ liệu tiền định và có sẵn trong IL, vì thế tất các các ngôn
ngữ hướng NET framework sẽ sinh ra mã cuối trên cơ sở các kiểu dữ liệu này
Trong ví dụ trên, VB.NET's Integer thực tế là một 32-bit signed integer, được ánh xạ từ kiểu Int32 trong IL Nó phải được biên dịch thành mã IL Bởi vì trình biên dịch C# cũng biết kiểu
dữ liệu này nên không có vấn đề gì cả Ở cấp mã nguồn, C# gọi Int32 là int, vì vậy khi biên dịch hàm VB.NET đơn giản trả về một kiểu int
CTS không chỉ đơn thuần là các kiểu dữ liệu đơn giản, doesn't merely specify primitive data types, mà nó còn cho phép chúng ta tự định nghĩa kiểu của riêng mình
Các kiểu được trình bày trong bảng dưới đây:
Type Kiểu cơ bản dùng để mô tả các kiểu khác
Value Type Kiểu cơ bản dùng để mô tả các kiểu giá trị
Reference Types Kiểu cơ bản dùng để môt tả các kiểu tham trị
Built-in Value Types Bao gồm các kiểu giá trị nguyên thủy chuẩn, như các kiểu số,
kiểu luận lí, kiểu kí tự
Enumerations Bộ các giá trị liệt kêSets of enumerated values
User-defined Value Types Kiểu được định nghĩa trong mã nguồn như là một kiểu giá trị
Trong C# nó có là struct
Interface Types Các giao diện
Pointer Types Các con trỏ
Self-describing Types Kiểu dữ liệu có quản
Arrays Các kiểu chứa mảng các đối tượng
Class Types Các kiểu tự mô tả nhưng không phải là mảng
Delegates Kiểu được thiết kế để tham chiếu đến các phương thức
User-defined Reference Types Kiểu được định nghĩa trong mã nguồn và được lưu như là kiểu
tham chiếu Trong C#, nó có nghĩa là một lớp
Boxed Value Types Một kiểu giá trị được bọc thành một kiểu tham chiếu vì thế nó
có thể được lưu trong heap
Chúng ta không thể liệt kê tât cả các kiểu giá trị ở đây, bởi vì chúng sẽ được bàn kĩ trong chương 2 Trong C#, mỗi kiểu có sẵn được nhận dạng bởi trình biên dịch ánh xạ đến một kiểu
IL cài sẵn Điều này cũng đúng cho cả VB.NET
Common Language Specification (CLS)
Trang 17Common Language Specification hoạt động cùng với Common Type System để bảo đảm thực thi ngôn ngữ chéo CLS là một bộ con chuẩn mà tất cả các trình biên dịch hướng NET đều phải hỗ trợ Đều đó có nghĩa là các trình biên dịch đều sẽ hỗ trợ tất cả những gì được định nghĩa trong CLS
Chú ý: Các bạn có thể viết các mã non-CLS, tuy nhiên những mã này không đảm bảo việc thực thi ngôn ngữ chéo
IL là một ngôn ngữ phân biệt loại kí tự Những nhà phát triển khi làm việc với các ngôn ngữ phân biệt loại kí tự có khả năng tạo nên sự mềm dẻo khi đặt tên biến VB.NET, lại không phải
là ngôn ngữ phân biệt loại kí tự CLS xử lí việc này bằng các ra hiệu cho CLS rằng mã không cho phép hai tên chỉ khác nhau về mặt loại kí tự Bởi vậy, mã VB.NET có thể hoạt động trong CLS
CLS hoạt động theo hai định hướng Trước tiên nó là một trình biên dịch riêng không hỗ trợ đây đủ các đặc trưng của NET điều này khuyến khích sự phát triển của các ngôn biết NET khác Thứ hai, nó bảo đảm rằng nếu bạn hạn chế các lớp của bạn trong những đặc tính của CLS, thì nó bảo đảm rằng các mã dùng trong những ngôn ngữ khác có thể dùng các lớp này Nét đẹp của ý tưởng này là việc giới hạn trong những đặc tính của CLS chỉ nên áp dụng cho những thành phần public và protected của các lớp và chỉ dùng cho các lớp public Trong các thành phần thực thi của các lớp của bạn, bạn có thể viết các mã non-CLS nếu muốn, bởi các ngôn ngữ khác không bao giờ có thể truy cập vào những phần này
Chúng ta không đi vào chi tiết của CLS ở đây Về mặt tổng quát CLS không ảnh hưởng nhiều đến mã C# của bạn vì nó không có nhiều đặc tính khác CLS
Garbage Collection
Garbage collector là một thành phần quản lí bộ nhớ của NET, nó là một đáp án cho việc thu
hồi bộ nhớ của các chương trình thực thi Từ trước đến giờ có hai công nghệ được sử dụng cho việc huỷ bộ nhớ trong Windows, những tiến trình này được yêu cầu từ hệ thống:
Ứng dụng tự làm điều này một cách thủ công
Tạo một bộ đếm tham chiếu đến đối tượng
Việc mã ứng dụng chịu trách nhiệm thu hồi vùng nhớ là một cộng nghệ dùng ở mức thấp, hoặc những ngôn ngữ thực thi cấp cao như C++ Nó mang tính hiệu quả cao, nó có thuận lợi
là tài nguyên sẽ được giải phóng ngay khi không còn cần thiết Một bất lợi lớn là nó thường xuyên sinh lỗi Mã nguồn luôn phải chỉ rõ cho hệ thống biết khi nó không cần dùng bộ nhớ đó nữa Dễ dàng nhìn ra rằng kết quả có thể dẫn đến rò rỉ bộ nhớ
Mặc dù các môi trường phát triển hiện đại có cung cấp một số công cụ giúp đỡ trong việc phát hiện sự rò rỉ bộ nhớ, nhưng rất khó theo vết, bởi vì nó không có hiệu lực cho đến khi có một khối lượng lớn bộ nhớ bị rò rỉ: Windows buộc phải ngưng các tiến trình xử lí Tại thời điểm này máy tính chậm đi thấy rõ một sự trả giá cho các yêu cầu bộ nhớ
Việc duy trì một bộ đếm các tham chiếu là một ân huệ trong COM Ý tưởng này cho rằng mỗi thành phần COM chứa một bộ đếm xem có bao nhiêu ứng dụng đang chứa tham chiếu đến nó Khi bộ đếm này xuống đến zero, Thành phần có thể tự hủy nó và giải phóng vùng nhớ cũng
Trang 18như các tài nguyên tương ứng Vấn đề ở đây là nó vẫn lệ thuộc vào sự thông báo của các ứng dụng khi chúng không còn dùng đến các thành phần này nữa Trong một vài trường hợp, nó
có khả năng tạo ra một vấn đề nghiêm trọng hơn là sự kiểu rò rỉ C++ thông thường, bởi vì đối tượng COM có thể nằm trong một tiến trình của riêng nó, điều này có nghĩa là nó sẽ không bao giờ được hủy bởi hệ thống (chí ít trong rò rỉ kiểu C++, hệ thống có thể giành lại toàn bộ vùng nhớ khi tiến trình kết thúc)
Thời gian chạy NET hoàn toàn phụ thuộc vào garbage collector instead Đây là một chương
trình hỗ trợ việc thu dọn bộ nhớ Trong ý tưởng này tất cả các yêu cầu bộ nhớ đều được cấp phát trên heap (điều này đúng cho tất cả các ngôn ngữ, trong NET, CLR chứa nó trong vùng heap có quản cho tất cả các ứng dụng NET sử dụng) Thỉnh thoảng NET sẽ kiểm tra xem vùng heap có quản có trở nên đầy chưa để nó tiến hành thu dọn, và nó gọi đây là tiến trình thu gôm rác Trình thu dọn rác sẽ kiểm tra các tham chiếu từ mã của bạn, ví dụ các tham chiếu từ
mã của bạn đến các đối tượng được lưu trên heap được nhận dạng, nó có nghĩa là đối tượng
đó vẫn còn tham chiếu, các đối tượng không còn tham chiếu nữa sẽ bị huỷ
Trình thu gom rác hoạt động trong NET bởi vì Intermediate Language được thiết kế để làm điều đó Phải tuân thủ các nguyên tắc sau, thứ nhất bạn chỉ có thể tham chiếu đến một đối tượng có sẵn bằng cách sao chép cac tham chiếu có sẵn, thứ hai Intermediate Language bảo
vệ kiểu, điều này có nghĩa là các tham chiếu đến các đối tượng có sẵn luôn chứa đựng thông tín nhận dạng chính xác của đối tượng đó
C++ Có thể không sử dụng trình thu gom một cách máy móc, bởi vì C++ cho phép các con trỏ tự do ép kiểu
Một điều đặc biệt quản trọng là tính không định trước của trình thu gom rác Hay nói cách khác, bạn không thể bảo đảm được khi nào trình thu gôm rác sẽ được gọi; nó sẽ được gọi khi CLR cảm thấy cần (nếu bạn không thực hiện lời gọi tường minh)
Bảo mật
.NET thật sự xuất sắc trong việc bổ sung cơ chế bảo mật của Windows bởi vì nó hỗ trợ
code-based security trong khi đó Windows chỉ thật sự hỗ trợ Role-code-based security
Role-based security là cơ sở để xác định tài khoản của các tiến trình đang thực thi, hay nói
cách khác ai sở hữu các tiến trình đang thực thi Code-based security là một cơ chế khác để xác định xem những mã nào và có bao nhiêu mã là đáng tin Cảm ơn sự bảo vệ kiểu mạnh của
IL, vì nhờ nó mà CLR có thể kiểm tra mã trước khi chạy trong một chế độ bảo vệ được đưa ra.NET cũng hỗ trợ một cơ chế những mã nào được phép phơi tra trong một cơ chế bảo mật nào đó
Một điều quan trọng là code-based security có thể làm giảm nguy cơ liên quan đến việc chạy
các đoạn mã có xuất xứ không rõ ràng (chẳng hạn như mã mà bạn downloaded từ Internet) Một ví dụ, nếu mã được chạy dưới quyền administrator, nó có thể sử dụng code-based
security để khai báo rằng mã không còn cho phép thực thi trong những kiểu mà quyền
administrator hỗ trợ như: không thể đọc hoặc viết lên các biến môi trường, đọc hoặc viết lên registry, không truy cập vào các đặc trưng trong NET
Security sẽ được bàn kĩ hơn trong chương 23
Trang 19đó
Trước thời NET, sự lựa chọn giữa cho phép các thể hiện đó có thể dùng trong một tiến trình, cái mà sẽ mang lại sự rủi ro có thể làm giảm độ an toàn của trang web, hay là cho phép các thể hiện đó chạy trên các tiến trình biệt lập, cái mà sẽ mang lại sự gia tăng sự thực thi
Giờ đây, đó là sự biệt lập mã thông qua các tiến trình Khi bạn kích khởi một ứng dụng mới,
nó sẽ chạy trong ngữ cảnh của tiếnt trình Các tiến trình Windows độc lập nhau thông qua vùng địa chỉ Trong ý tưởng này mỗi tiến trình sẽ có sẵn 4 gigabytes bộ nhớ ảo để chữa dữ liệu và mã thực thi (4GB là dành cho hệ thống 32-bit; hệ thống 64-bit có thể nhiều hơn) Windows gián tiếp thực hiện cơ chê mở rộng để ánh xạ bộ nhớ ảo này với bộ nhớ vật lí thật hay đĩa Mỗi tiến trình sẽ có sự ánh xạ khác nhau, sao cho các vùng nhớ vật lí thật sự không trùng lấp nhau Nó được minh họa bởi sơ đồ sau:
Một cách tổng quat, bất kì tiến trình nào cũng chỉ có thể truy cập đến bộ nhớ thông qua mộ địa chỉ ảo cụ thể - các tiến trình không thể truy xuất trực tiếp bộ nhớ vật lí Như vậy nó đơn giản là không cho phép một tiến trình có thể truy xuất đến vùng nhớ được cấp cho một tiến trình khác Nó cung cấp một cơ chế bảo đảm rằng những ứng xử tồi của mã không thể làm hỏng bất kì thứ gì bên ngoài vùng địa chỉ của nó (chú ý rằng trong Windows 9x, những cơ chế bảo vệ này không đươc thấu đáo như trong NT/2000/XP, vì thế về mặt lí thuyết các ứng dụng có khả năng phá hủy Windows do viết lên vùng nhớ không thích hợp)
Các tiến trình không chỉ phục vụ như là cách để tạo nên sự tách biệt giữa các thể hiện khác nhau Trong hệ thống Windows NT/2000, nó còn làm đơn vị để gán các giấy phép và đặc
Trang 20quyền bảo mật Mỗi tiến trình có một kí hiệu bảo mật riêng, để báo cho Windows biết chính xác các thực thi mà tiến trình cho phép
Cả hai phương pháp này đều có khả năng bảo mật tốt nhưng lại sinh ra một bất lợi lớn đó là thực thi Thông thường các tiến trình sẽ hoạt động chung với nhau, bởi vậy cần phải có sự truyền thông giữa chúng Ví dụ như đâu đó một tiến trình gọi một thành phần COM khả thi,
và bởi vì được yêu cầu chạy trong tiến trình của chúng Giống như cách mà COM vẫn làm Khi đó các tiến trình không thể dùng chung bộ nhớ, một tiến trình phức tạp được sử dụng để sao chép dữ liệu giữa các tiến trình Nó sẽ gây trở ngại lớin đến vấn đề thực thi Nếu bạn muốn các thành phần có thể làm việc với nhau mà không muốn ảnh hưởng đến vấn đề thực thi, cách duy nhất là sử dụng DLL-based components và mọi thứ sẽ hoạt động trong cùng một vùng đã chỉ (đây là một việc mạo hiểm vì các thành phần ứng xử tồi sẽ làm hỏng tất cả mọi thứ)
Application domains được thiết kế như là một thành phần riêng biệt không gây ảnh hưởng
đến vấn đề thực thi trong lúc các tiến trình trao đổi dữ liệu Ý tưởng này cho rằng một tiến trình được chia thành một số các application domains Mỗi application domain sẽ trả lời cho một ứng dụng đơn, và các loạt thực thi sẽ hoạt động như là một application domain độc lập:
Nếu các thực thi cúng sử dụng chung một vùng nhớ, rõ ràng chúng có thể dùng chung dữ liệu, bởi vì trên lí thuyết chúng có thể truy xuất trục tiếp dữ liệu của nhau Tuy nhiên đó chỉ là nguyên tắc, CLR sẽ bảo đảm rằng điều này sẽ không xảy ra trong thực tế bằng cách kiểm tra
kỹ lưỡng mã trong mỗi ứng dụng, để chắc rằng chúng không lạc ra khỏi vùng dữ liệu của chúng Trước tiên hầu như các trò bịp quá đáng sẽ bị loại bỏ, sau đó ứng dụng có thể hoạt động và không phải kích hoạt nó
Thật sự, nó hoàn toàn có thể làm được điều này vì sự định kiểu mạnh của IL Trong nhiều trường hợp, nếu mã thật sự dùng kiểu không quản chẳng hạn như các con trỏ, kiểu dữ liệu đang dùng sẽ bảo đảm vùng nhớ sẽ được truy cập hợp lí ví dụ, kiểu mảng NET sẽ tiến hành kiểm tra và bảo đảm rằng các thao tác trên mảng đều nằm trong phạm vi cho phép Nếu một thực thi cần trao đổi thông tin với các thực thi chạy trong các application domain khác chúng phải gọi dịch vụ điều khiển từ xa của NET
Mã được kiểm tra xem có truy cập dữ liệu ngoài application domain không được gọi là
memory type-safe Như vậy mã này có thể hoạt động cùng với mã được bảo vệ ở các
application domains khác nhau trong cùng một tiến trình
Trang 21Bẫy lỗi thông qua các ngoại lệ
.NET được thiết kế để đơn giản hoá quá trình bẫy lỗi thông qua các ngoại lệ Những nhà phát triển C++ nên biết rằng, bởi vì IL là hệ thống định kiểu mạnh, nó không thực thi các mối kết hợp bất lợi thông qua các ngoại lệ trong IL, đây là cách được đưa ra trong C++ Tất nhiên khối finally cũng được hỗ trợ trong NET và C#
Chúng ta sẽ bàn kĩ về ngoại lệ trong chương 4 Sơ qua một chút, ý tưởng ở đây là một vùng
mã được thiết kế như là các thủ tục quản ngoại lệ, mỗi đoạn mã có thể giải quyết một điêu kiện lỗi riêng (ví dụ, một file không được tìm thấy, hoặc không được phép thực thi một số lệnh) Những điều kiện này có thể được định nghĩa kĩ hoặc sơ qua tuỳ bạn Cấu trúc ngoại lệ bảo đảm rằng khi một điều kiện sinh lỗi xảy ra, ngay lập tức luồn thi hành sẽ nhảy đến thủ tục quản ngoại lệ
Cơ cấu quản ngoại lệ tạo điều kiện thuận lợi để truyền cho một đối tượng thông tin chính xác
về các điều kiện sinh ngoại lệ và một thủ tục quản ngoại lệ Đối tượng này có thể bao gồm một thông điệp thích hợp cho người dùng và chi tiết về nơi phát sinh ngoại lệ
Hầu hết các cơ cấu quản ngoại lệ, bao gồm cả điều khiển của chương trình sẽ treo khi một ngoại lệ được phát sinh, được quản bởi ngôn ngữ bậc cao (C#, VB.NET, C++), và không một lệnh IL nào hỗ trợ việc đó Ví dụ C#, quản sự kiện thông qua các khối mã try{}, catch{}, finally{}, chúng ta sẽ bàn sau trong chương 4
Những gì mà NET làm là cung cấp cơ sở cho phép các trình biên dịch hướng NET hỗ trợ việc quản ngoại lệ Cụ thể nó cung cấp một bộ các lớp NET có thể miêu tả các ngoại lệ, và thực thi ngôn ngữ chéo cho phép truyền các đối tượng ngoại lệ cho các mã quản ngoại lệ, bất chấp mã quản ngoại lệ được viết trong ngôn ngữ nào Sự độc lập ngôn ngữ này không được
hỗ trợ trong việc quản ngoại lệ của C++ lẫn Jave, mặc dù nó vẫn tồn tại giới hạn trong cơ cấu COM cho việc quản lỗi: bao gồm việc trả về mã lỗi trong các phương thức và truyền các đối tượng lỗi Thật vậy các ngoại lệ đó được quản một cách nhất quán trong các ngôn ngữ khác nhau nó đóng vai trò quyết định trong phát triển đa ngôn ngữ
Dùng các thuộc tính
Attributes là một đặc trưng đã thân thuộc với những nhà phát triển C++ để viết các thành
phần COM (thông qua việc sử dụng Microsoft's COM Interface Definition Language (IDL))
dù vậy nó không thân thiện với những nhà phát triển Visual Basic hay Java Attribute cung cấp thông tin mở rộng liên quan đến các mục trong chương trình có thể được sử dụng bởi trình biên dịch
Attributes được hỗ trợ trong NET - và vì thế giờ đây nó được hỗ trợ trong C++, C#, và VB.NET Một cái mới là các attribute trong NET là một cơ chế cho phép bạn có thể định nghĩa các attribute của riêng bạn trong mã nguồn Các attribute tự định nghĩa này có thể thay thế cho các siêu dữ liệu của các phương thức và kiểu dữ liệu tương ứng .Do tính độc lập ngôn ngữ của NET mà các attribute có thể được định nghĩa trong một ngôn ngữ và có thể đọc bằng
mã ở các ngôn ngữ khác
Attributes sẽ được bàn trong chương 5 của cuốn sách này
Trang 222.5 Các lớp của NET Framework
Các lớp NET Framework
Cĩ lẽ một trong những lợi ích lớn nhất của viết mã cĩ quản, ít nhất là đối với một nhà phát
triển, đĩ là bạn cĩ thể sử dụng thư viện lớp cơ sở của NET
Thư viện lớp cơ sở của NET là một tập hợp lớn các lớp mã cĩ quản được viết bởi Microsoft, những lớp này cho phép bạn thao tác rất nhiều các tác vụ sẵn cĩ trong Windows Bạn cĩ thể tạo các lớp của mình từ các lớp cĩ sẵn trong thư viện lớp cơ sở của NET dựa trên cơ chế thừa
kế đơn
Thư viện lớp cơ sở của NET rất trực quan và rất dễ sử dụng Ví dụ, để tạo một tiến trình mới, bạn đơn giản gọi phương thức Start() của lớp Thread Để disable một TextBox, bạn đặt thuộc tính Enabled của đối tượng TextBox là false Thư viện này được thiết kế để dễ xài như là Visual Basic và Java Tất nhiên là nĩ dễ sử dụng hơn các lớp của C++: các vỏ bọc ngồi các hàm API thơ như GetDIBits(), RegisterWndClassEx(), và IsEqualIID()
Mặt khác, những nhà phát triển C++ luơn dễ dàng truy cập đến các API, ngược lại những nhà phát triển Visual Basic và Java đã bị giới hạn trong những thao tác hệ thống cơ bản mà ngơn ngữ đã từng ngơn ngữ đã cung cấp sẵn Cái mới của thư viện lớp cơ sở NET là kết hợp tính đơn giản của các thư viện Visual Basic và Java với hầu hết các đặc tính trong các hàm
Windows API Cĩ nhiều đặc tính của Windows khơng sẵn cĩ trong các lớp của thư viện NET, trong trường hợp đĩ bạn cần phải gọi các hàm API, những đặc tính này thường là các đặc tính lạ, ít sử dụng Những đặc tính thơng dụng đều đã được hỗ trợ đầy đủ trong thư viện lớp của NET Và nếu bạn muốn gọi một hàm API, NET gọi là "platform-invoke", cơ chế này luơn bảo đảm tính đúng đắn của kiểu dữ liệu, vì vậy thao tác này khơng khĩ hơn việc gọi trực tiếp từ mã C++, nĩ được hỗ trợ cho cả C#, C++, và VB.NET
WinCV, một tiện ích Windows-based, bạn cĩ thể dùng để tham khảo các lớp, cấu trúc, giao diện, kiểu liệt kê trong thư viện NET base class Chúng ta sẽ tìm hiểu WinCV trong chương 6
Dù rằng chủ đề của chương 5 bàn về các lớp cơ sở, nhưng thực tế, chúng tơi chỉ nĩi về các cú pháp của ngơn ngữ C#, chủ yếu quyển sách này chỉ cho các bạn về cách dùng các lớp khác nhau trong thư viện NET base class Một cách tổng quát NET base classes bao gồm các vấn đề:
Các đặc tính lõi cung cấp bởi IL (chủ yếu là về các kiểu dữ liệu trong CTS, Chương 5)
Hỗ trợ Windows GUI và controls (Chương 7)
Web Forms (ASP.NET, 16)
Data Access (ADO.NET, 10)
Directory Access (Chương 13)
File system và registry access (Chương 12)
Networking và web browsing (Chương 20)
NET attributes và reflection (Chương 5)
Truy xuất vào hệ điều hành Windows (các biến mơi trường vv , Chương 23)
COM interoperability (18)
Một cách tình cờ, hầu hết các thư viện lớp cơ sở của NET được viết bằng C#!
Trang 23Các Namespace
Namespace là cách mà NET dùng để chống lại sự xung đột tên giữa các lớp Chẳng hạn như trường hợp bạn cĩ một lớp mơ tả khách hàng gọi là lớp Customer, và sau đĩ một người khác cũng cĩ một lớp giống như vậy
Một namespace khơng chỉ là một nhĩm các kiểu dữ liệu, mà nĩ làm cho tên của tất cả các kiểu dữ liệu trong cùng một khơng gian tên sẽ cĩ tiếp đầu ngữ là tên của namespace đĩ Nĩ cũng cho phép một khơng gian tên nằm trong một khơng gian tên khác Ví dụ, hầu hết các hỗ trợ chung của các thư viện lớp cơ sở NET đều nằm trong một khơng gian tên gọi là System Lớp cơ sở Array nằm trong khơng gian tên này cĩ tên đầy đủ là System.Array
.NET yêu cầu tất cả các kiểu đều phải được định nghĩa trong một khơng gian tên, ví dụ bạn cĩ thể đặt lớp Customer của bạn trong một khơng gian tên gọi là YourCompanyName Lớp này
sẽ cĩ tên đầy đủ là YourCompanyName.Customer
Nều một namespace khơng được khai báo rõ ràng, các kiểu sẽ được đặt vào một namespace tồn cục khơng tên
Microsoft khuyên rằng các hỗ trợ của bạn nên đặt vào một namespace ít nhất là 2 cấp, cấp một là tên của cơng ty của bạn, cấp hai là tên của cơng nghệ hoặc là phần mềm của gĩi sản phẩm đĩ, chẳng hạn như YourCompanyName.SalesServices.Customer Làm như vậy trong hầu hết các trường hợp đảm bảo rằng, các lớp trong ứng dụng của bạn khơng xung đột tên với các lớp của các tổ chức khác
Chúng ta sẽ xem xét thêm về namespace ở chương 2
2.6 Tạo ra các ứng dụng NET bằng C#
Tạo các ứng dụng NET bằng C#
C# cĩ thể dùng để tạo các ứng dụng console: các ứng dụng thuần văn bản chạy trên DOS window Hầu như bạn chỉ tạo các ứng dụng console khi cần kiểm tra các thư viện lớp, hoặc cho các tiến trình daemon Unix/Linux Tât nhiên, bạn cũng cĩ thể dùng C# để tạo các ứng dụng dùng cho các cơng nghệ tương thích NET Trong phần này, chúng ta xem qua về các kiểu ứng dụng khác nhau cĩ thể tạo ra bằng C#
Tạo các ứng dụng ASP.NET
ASP là một cơng nghệ của Microsoft dùng để tạo các trang web cĩ nội dung động Một trang ASP thực chất là một file HTML cĩ nhúng các khối server-side VBScript hay JavaScript Khi một trình duyệt khách yêu cầu một trang ASP page, web server sẽ sinh ra mã HTML, xử lí các server-side script khi chúng đến Thường thì các script sẽ truy cập vào một cơ sở dữ liệu
để lấy dữ liệu, và biểu diễn trên trang HTML ASP là cách đơn giản nhất để tạo các ứng dụng browser-based
ASP tất nhiên cũng cĩ một vài hạn chế Trước tiên, các trang ASP thỉnh thoảng trở nên rất chậm bởi vì mã server-side được thơng dịch thay vì đựơc biên dịch Thứ hai, các file ASP
Trang 24khó bảo trì bởi vì chúng không có cấu trúc; mã server-side ASP và HTML được trộn lẫn với nhau Thứ ba, ASP đôi khi kho phát triển bởi nó không quan tâm đến bẫy lỗi và kiểm tra kiểu
Cụ thể, nếu bạn dùng VBScript và muốn bẫy lỗi trên các trang của bạn, bạn phải dung câu lệnh On Error Resume Next, và cho phép tất cả các thành phần gọi thông qua một
Err.Number để chắc rằng tất cả đều tốt
ASP.NET là một phiên bản mới của ASP đã cải tiến rất nhiều các thiếu xót của nó Nó
không chỉ thay thế ASP; hơn thế, các trang ASP.NET có thể sống chung với các ứng dụng ASP trên cùng một máy chủ Tất nhiên bạn có thể lập trình ASP.NET với C#!
Mặt dù các chương (14-16) sẽ bàn kĩ về ASP.NET, nhưng chúng ta cũng nói qua một vài đặc tính quan trọng của nó
Các đặc tính của ASP.NET
Trước tiên, và có lẽ là quan trọng nhất, các trang ASP.NET là các trang có cấu trúc Có nghĩa
là mỗi trang là thực tế là một lớp được thừa kế từ lớp NET System.Web.UI.Page, và có thể ghi đè một tập các phương thức sẽ dùng trong thời gian sống của trang web (bạn hãy tưởng tượng rằng nhữn sự kiện này như là anh em bà con với các sự kiện OnApplication_Start và OnSession_Start trong file global.asa của ASP cũ.) Bởi vì bạn có thể chuyển các thao tác của một trang thành các sự kiện sáng nghĩa hơn, chính vì thể mà các tramg ASP.NET dễ hiểu hơn
Một điểm mạnh khác là các trang ASP.NET có thể được tạo trong VS.NET, cùng chung môi trường với các thành phần luận lí và dữ liệu sẽ được dùng trong các trang web này Một nhóm
đề án VS.NET, hoặc solution, chứa tất cả các file liên quan đển một ứng dụng Hơn thế nữa
bạn có thể bẫy lỗi các trang ASP của bạn ngay trong trình thiết kế; trước đây, thật là khó khăn
để có thể cấu hình InterDev và các đề án web server để thực hiện bẫy lỗi
Rõ ràng, đặc tính ASP.NET's code-behind giúp các bạn có thể dễ dàng cấu trúc một trang web ASP.NET cho phép bạn tách biệt các chức năng server-side của trang thành một lớp, biên dịch lớp đó thành một DLL, và đặt DLL đó vào một thư mục bên dưới phần HTML Một code-behind chi phối đỉnh của một trang web tương đương với file DLL của nó Khi một trình duyệt yêu cầu trang, web server phát ra các sự kiện trong lớp của page's code-behind DLL
Cuối cùng không kém phần quan trọng, ASP.NET thật sự đáng chú ý với khả năng tăng cường sự thực thi Ngược lại với các trang ASP được thông dịch cho mỗi yêu cầu, web server lưu giữ lại các trang ASP.NET sau quá trình biên dịch Nghĩa là các yêu cầu sau của một trang ASP.NET sẽ thực thi nhanh hơn trang đầu tiên
ASP.NET dễ tạo các trang hơn bởi vì nó được chiếu bởi trình duyệt, bạnc có thể sử dụng một môi trường mạng intranet Theo kinh nghiệm truyền thống thì một ứng dụng form-based thường là tốt hơn một user interface, nhưng cũng khó bảo trì hơn vì nó chạy trên nhiều máy khác nhau
Với sự ra đời của Internet Explorer 5 và sự thực thi mơ hồ của Navigator 6, tất nhiên các đặc tính của ứng dụng form-based bị che mờ IE 5's hỗ trợ nhất quán và mạnh mẽconsistent cho DHTML cho phép các nhà lập trình tạo các ứng dụng web-based đẹp là lớn hơn Tất nhiên, các ứng dụng này bắt buộc phải theo chuẩn của IE và không được hỗ trợ bởi Navigator Trong nhiều lĩnh vực công nghiệp, chuẩn này đã trở nên phổ biến
Trang 25Web Forms
Để dễ dàng cho việc tạo các trang có cấu truc, Visual Studio NET cung cấp Web Forms
Chúng cho phép bạn tạo các trang ASP.NET sinh động như cách mà VB 6 hay C++ Builder windows đã làm; nó cách khác, bằng cách kéo các controls từ toolbox vào form, sau đó sắp xếp cho đẹp, điền mã quản lí sự kiện thích hợp vào control đó Khi bạn dung C# để tạo các Web Form, bạn đang tạo một lớp C# được thừa kế từ lớp Page base, và một trang ASP được chỉ định như là code-behind Tất nhiên, không bắt buộc phải dùng C# để tạo một Web Form; bạn có thể dùng VB.NET hoặc một ngôn ngữ biết NET khác
In the past, the difficulty of web development has discouraged some teams from attempting it
To succeed in web development, you had to know so many different technologies, such as VBScript, ASP, DHTML, JavaScript, and so on By applying the Form concepts to web pages, Web Forms promise to make web development easier Only time will tell, however, how successful Web Forms and Web Controls (which we'll look at next) will be at insulating the developer from the complexities of web design
Web Controls
Các control thường được cư trú trên một Web Form không phải là các ActiveX control Hơn nữa, chúng là XML tags trong ASP namespace và browser có thể chuyển sang HTML và client-side script khi một trang được yêu cầu Đặc biệt hơn, web server có thể các điều khiển server-side control theo nhiều cách khác nhau, sinh ra sự biến đổi phù hợp với các yêu cầu của các web browser riêng biệt Điều này có nghĩa là sẽ dễ dàng viết các giao diện người dùng tinh vi cho các trang web, đừng bận tâm đến vấn đề tương thích trình duyệt web– bởi vì Web Forms sẽ làm điều đó cho bạn
Bạnc có thể dùng C# hay VB.NET để mở rộng hộp công cụ Web Form Việc tạo một side control mới đơn giản là thực thi lớp NET System.Web.UI.WebControls.WebControl
server-Web Services
Ngày nay, các trang HTML là nguyên nhân của hầu hết các xung đột trên World Wide Web Với XML, các máy vi tính có một định dạng device-independent để dùng cho việc truyền thông với các máy khác trên mạng Web Trong tương lại, các máy tính có thể sẽ dùng Web và XML để trao đổi thông tin hơn là dùng các line chuyên dụng và theo những định dạng riêng
như EDI (Electronic Data Interchange) Các Web Service được thiết kế cho một web hướng
dịch vụ, trong đó các máy tính ở xa cung cấp cho nhau các thông tin động có thể phân tích và tái định dạng, trước khi trao lại cho người dùng Một Web Service là cách đơn giản nhất để một máy tính có thể cung cấp thông tin cho các máy tính khác trên Web dưới định dạng XML
Về mặt kĩ thuật, một Web Service trong NET là một trang ASP.NET theo định dạng XML thay vì theo định dạng HTML để yêu cầu các client Các trang này có một code-behind DLL chứa một lớp xuất phát từ lớp WebService VS.NET IDE cung cấp một cơ chế để tiện cho việc phát triển Web Service
Có hai lí do chính để một tổ chức chọn Web Services Lí do thứ nhất là bởi vì chúng đáng tin cậy trên HTTP, Web Services có thể dùng các mạng có sẵn (the Web) như một môi trường
Trang 26cho việc truyền thông Một lí do khác là bởi vì các Web Service dùng XML, một định dạng
dữ liệu tự mô tả, mang tính phổ biến, và độc lập nền
Tạo các Windows Form
Mặc dù C# và NET được thiết kế để phát triển web, nhưng chúng vẫn hỗ trợ mạnh mẽ cho cái gọi là ứng dụng "fat client", các ứng dụng có thể được cài đặt trên một máy người dùng
cuối Hỗ trợ này gọi là Windows Forms
Một Windows Form là câu trả lời của NET cho VB 6 Form Dùng để thiết kế một giao diên window sinh động, bạn chỉ đơn giản kéo các control từ vào trên Windows Form Để xác định cách xử của window, bạn viết các thủ tục quản lí sự kiện cho form controls Một đề án
Windows Form được dịch thành một EXE phải được cài đặt trong một môi trường ở máy tính người dùng cuối Giống như các kiểu đề án NET khác, đề án Windows Form được hỗ trợ cho
cả VB.NET và C# Chúng ta sẽ nói kĩ về Windows Forms trong chương 7
Windows Controls
Mặc dù Web Forms và Windows Forms được phát triển theo cùng một cách, bạn dùng các loại khác nhau của controls để định vị chúng Web Forms dùng Web Controls, và Windows
Forms dùng Windows Controls
Một Windows Control là một ActiveX control Đằng sau sự thực thi của một Window control,
là sự biên dich sang một DLL để có thể cài đặt trên máy khách Thật vậy, NET SDK cung cấp một tiện ích dùng để tạo một vỏ bọc cho các ActiveX control, vì thể chúng có thể được đặt trong Windows Forms Giống trường hợp này các Web Control, Windows Control được tạo thành từ một lớp khác System.Windows.Forms.Control
Windows Services
Một Windows Service là một chương trình được thiết kế để chạy trên nền Windows
NT/2000/XP (không hỗ trợ trên Windows 9x) Các dịch vụ này rất hữu ích khi bạn muốn một chương trình có thể chạy liên tục và sẵn sàng đáp ứng các sự kiện mà không cần người dùng phải khởi động Ví dụ như một World Wide Web Service ở trên các web server luôn lắng nghe các yêu cầu từ trình khách
Thật dễ dàng để viết các dịch vụ trong C# Với thư viện lớp cơ sở NET Framework sẵn có trong không gian tên System.ServiceProcess namespace chuyên dùng để tổ chức các tác vụ boilerplate kết hợp với các dịch vụ, ngoài ra, Visual Studio NET cho phép bạn tạo một đề án C# Windows Service, với các mã nguồn cơ bản ban đầu Chúng ta sẽ khám cách viết một C# Windows Services trong chương 22
Trang 272.7 Vai trò của C# trong kiến trúc
.NET Enterprise
C# yêu cầu phải cĩ NET runtime, trong một vài năm tới hầu hết các máy khách đặc biệt là các máy để bàn sẽ được cài NET Vào lúc đĩ, việc cài đặt các ứng dụng C# sẽ giống như việc tái phân phối các thành phần NET Sẽ cĩ nhiều ứng dụng C# được cài đặt trong mơi trường thương mại Thật vậy, C# được coi như là một cơ hội nổi bật cho các tổ chức để cĩ thể tạo những ứng dụng mạnh mẽ, những ứng dụn client-server n-lớp
Khi kết nối với ADO.NET, C# cĩ khả năng truy cập các cơ sở dữ liệu tổng quát và nhanh
chĩng như cơ sở dữ liệu SQL Server và Oracle Các datasets trả lại cĩ thể dễ dàng thao tác thơng qua các đối tượng của ADO.NET, và tự động trả về kiểu XML để truyền thơng trên một mạng intranet văn phịng
Một database schema được tạo ra cho một đề án, C# đủ thơng minh để thực thi các lớp đối tượng truy xuất dữ liệu để cĩ thể chèn, cập nhật, xố truy cập đến một bản dữ liệu khác
Để tạo một ứng dụng với C#, bạn nhất định sẽ đề án tạo một thư viên lớp các đối tượng truy xuất dữ liệu và các đối tượng thương mại Trong khi phát triển, bạn cĩ thể dùng Console projects để kiểm tra các phương thức của các lớp của bạn Một điều thú vị trong lập trình Console là nĩ cĩ thể tự động chạy các file BAT để kiểm tra một nhĩm các mã lệnh
Chú ý rằng, C# và NET sẽ ảnh hưởng đến cách thức đĩng các gĩi vật lí cho việc dùng lại các lớp Trong quá khứ, rất nhiều nhà phát triển cĩ nhồi nhét các lớp vào một thành phần vật lí đơn bởi vì việc làm này giúp cho việc phát triển dễ dàng hơn, nếu xảy ra một lỗi nhận dạng phiên bản, bạn sẽ biết nĩ xảy ra ở đâu Bởi vì việc phát triển các thành phần NET thương mại đơn giản là thao tác copy các file vào một số thư mục, bây giờcác nhà phát triển đĩng gĩi các lớp của họ vào nhiều gĩi logic, các thành phần riêng biệt mà khơng phải lo lắng về việc xung đột "DLL Hell"
Cuối cùng khơng kém phần quan trọng, các trang ASP.NET được viết bằng C# tạo thành các giao diện người dùng thơng minh hơn Bởi vì các trang ASP.NET được biên dịch nên chúng
sẽ chạy nhanh hơn Cũng bởi chúng cĩ thể bẫy lỗi trong VS.NET IDE nên chúng mạnh mẽ hơn Do chúng hỗ trợ đầy đủ các đặc tính của ngơn ngữ như kết nối sớm, thừa kế, nên các trang ASP.NET được viết trong C# gọn gàng và dễ bảo trì
Các nhà phát triển cĩ thể hồi nghi về sự thổi phồng qua mức về cơng nghệ và ngơn ngữ mới,
và miễn cưỡng dùng các nền đơn giản bởi vì chúng đã từng tỏ ra hữu ích Nếu bạn là một nhà phát triển thương mại cho một bộ phận IT, hoặc nếu ban là nhà cung cấp các dịch vụ ứng dụng thơng qua World Wide Web, chúng tơi bảo đảm rằng C# và NET đưa ra khơng dưới bốn lợi ích lớn, thậm chí một vài đặc tính mà Web Services và server-side controls khơng giải quyết được:
Xung đột giữa các Component hiếm khi xảy ra và việc phát triển trở nên dễ dàng hơn,
do các phiên bản khác nhau của cùng một thành phần cĩ thể chạy song song nhau trên cùng một máy mà khơng gây ra xung đột
Mã ASP của bạn sẽ khơng cịn hỗn dộn nữa
Trang 28 Bạn sẽ được thừa kế rất nhiều chức năng tuyệt vởi của các NET base class
Đối với các ứng dụng yêu cầu một giao diện Windows Forms, C# sẽ là cách dễ nhất
để tạo các ứng dụng loại này
Windows Forms cĩ một vài điểm xuống hạng trong một vài năm trở lại đây do sự phát triển của WebForms và các ứng dụng Internet-based Tuy nhiên, nếu số ít các đồng nghiệp của bạn thơng thạo JavaScript, ASP, hoặc các cơng nghệ cĩ liên quan, thì Windows Forms vẫn là một
sự lựa chọn để tạo một giao diện dễ dàng và nhanh chĩng Nên nhớ ràng cần tách biệt mã của bạn để cho các logic giao diện người dùng tách biệt với các logic thương mại và các mã truy cập dữ liệu Làm như thế sẽ cho phép bạn di trú ứng dụng của bạn vào trình duyệt tại một vài thời điểm trong tương lai nếu cần thiết Dù vậy, Windows Forms vẫn sẽ cịn lấn át user interface trong các ứng dụng gia đình và các sản phẩm thương mại nhỏ trong một thời gian dài nữa
2.8 Tóm tắt
Tĩm tắt
Chúng ta đã khảo sát nhiều vấn đề trong chương này, chúng ta sẽ tĩm lại các vấn đề quan trọng trong NET Framework và mối quan hệ của nĩ với C# Chúng tơi đã trình bày cách mà tất cả các ngơn ngữ hướng NET được biên dịch thành Intermediate Language trước khi được biên dịch và thực thi bởi Common Language Runtime Chúng tơi cũng đã trình bày vai trị của các đặc tính sau trong NET trong quá trình biên dịch và thực thi:
Các Assembly và thư viện lớp cơ sở của NET
Trang 29Chúng tơi cũng đã trình bày những đặc trưng của IL, cụ thể là định nghĩa kiểu mạnh và hướng đối tượng Chúng tơi đã chú thích các đặc tính này ảnh hưởng đến các các ngơn ngữ hướng NET khác, bao gồm C# Chúng tơi cũng đã chú thich cách mà định nghĩ kiểu mạnh cĩ thể hỗ trợ tương hoạt ngơn ngữ chéo, cũng như các dịch vụ CLR chẳng hạn như trình thu gom rác và bảo mật
Ở phần cuối của chương tơi đã nĩi về cách tạo các ứng dụng C# dựa trên các cơng nghệ của NET trong đĩ cĩ ASP.NET
Giờ đây chúng ta đã cĩ cái nền, chương tới sẽ chỉ ra cách viết mã trong C#
3 Chương 2: Căn bản về C#
Khai báo biến
Khởi tạo và phạm vi hoạt động của biến
C#'s predefined data types
Cách sử dụng các vịng lặp và câu lệnh
Trang 30 Gọi và hiển thị lớp và phương thức
Phương thức của hàm Main( )
Cơ bản trình biên dịch dịng lệnh trong C#
Using System.Console để thực hiện I/O
Sử dụng chú thích trong C# và Visual Studio NET
Các định danh và từ khố trong C#
Cuối chương này bạn sẽ cĩ đủ khả năng viết một chương trình đơn giản bằng C# mà bạn khơng cần phải biết sự kế thừa hay hướng đối tượng mà chúng tơi sẽ trình bày những phần này ở vài chương tới của quyển sách
3.1 Trước khi bắt đầu
Trước khi bắt đầu !
Như chúng tơi đã đề cập C# là ngơn ngữ lập trình hướng đối tượng do đĩ chúng ta phải nắm
vững thế nào là class, objects, interface và inheritance Nếu trước đây bạn đã lập trình C++
hay Java thì bạn nên nắm vững nền của lập trình hướng đối tượng (OOP)
Nếu bạn chưa học qua lập trình hướng đối tượng thì cuốn sách này sẽ giúp bạn học nĩ, phụ lục A cĩ cung cấp cho bạn những hướng dẫn trong lập trình OOP
Nếu bạn là người đã cĩ kinh nghiệm trong VB 6, C++, hoặc Java bạn nên lưu ý sự so sánh
sự khác nhau của chúng tơi về C# và C++, Java, VB 6 chúng ta sẽ cĩ cái nhìn rõ hơn trong việc học C#
Bạn cĩ thể xem thêm tài liệu khi download từ web site của Wrox Press
(http://www.wrox.com) bạn sẽ được hướng dẫn chi tiết hơn Chúc bạn thành cơng
3.2 Chương trình C# đầu tiên
Chương trình đầu tiên !
Chúng ta sẽ bắt đầu theo cách truyền thống là tạo một chương trình viết bằng C# rồi cho biên dịch và chạy thử nghiệm Việc phân tích chương trình con này sẽ dẫn dắt bạn vào những chức năng chủ chốt của ngơn ngữ C#
Bạn cĩ thể biên dịch chương trình này bằng cách khỏ vào chương trình soạn thảo văn
bản đơn giản, Notepad chẳng hạn, rồi cho cất trữ dưới dạng tập tin với tên mở rộng là cs (tắt
chữ C sharp), rồi cho chạy trình biên dịch C# command_line (scs.exe) ví dụ tập tin First.cs :
Trang 31csc First.cs
Microsoft (R) Visual C# NET Compiler version 7.00.9466
for Microsoft (R) NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001 All rights reserved
3.3 Bieán
Một biến dùng để lưu trữ giá trị mang một kiểu dữ liệu nào đó
Cú pháp C# sau đây để khai báo một biến :
[ modifier ] datatype identifer ;
Với modifier là một trong những từ khoá : public, private, protected, còn datatype
là kiểu dữ liệu (int , long , float ) và identifier là tên biến
Thí dụ dưới đây một biến mang tên i kiểu số nguyên int và có thể được truy cập bởi bất cứ hàm nào
Trang 32// Chúng ta có thể khai báo thêm biến i ở đây
for (int i = 9; i >= 0; i )
Trang 33const int a = 100; // giá trị này không thể bị thay đổi
Trong định nghĩa lớp mà ta sẽ xem sau, người ta thường định nghĩa những mục tin (field) được gọi là read-only variable, nghĩa là những biến chỉ được đọc mà thôi
Hằng có những đặc điểm sau :
Hằng bắt buộc phải được gán giá trị lúc khai báo.Một khi đã được khởi gán thì không thể viết đè chồng lên
Trang 34 Trị của hằng phải cĩ thể được tính tốn vào lúc biên dịch, Do đĩ khơng thể gán một hằng từ một trị của một biến Nếu muốn làm thế thì phải sử dụng đến một read-only field
Hằng bao giờ cũng static, tuy nhiên ta khơng thể đưa từ khố static vào khi khai báo hằng
Cĩ ba thuận lợi khi sử dụng hằng trong chương trình của bạn :
Hằng làm cho chương trình đọc dễ dàng hơn, bằng cách thay thế những con số vơ cảm bởi những tên mang đầy ý nghĩa hơn
Hằng làm cho dễ sữa chương trình hơn
Hằng làm cho việc tránh lỗi dễ dàng hơn, nếu bạn gán một trị khác cho một hằng đâu
đĩ trong chương trình sau khi bạn đã gán giá trị cho hằng, thì trình biên dịch sẽ thơng báo sai lầm
3.4 Kiểu dữ liệu tiền định nghĩa
Dữ liệu kiểu trị và kiểu qui chiếu
C# là một ngơn ngữ được kiểm sốt chặt chẻ về mặt kiểu dữ liệu, ngồi ra C# cịn chia các
kiểu dữ liệu thành hai loại khác nhau: kiểu trị (value type) và kiểu qui chiếu (reference
type) Nghĩa là trên một chương trình C# dữ liệu được lưu trữ một hoặc hai nơi tuỳ theo đặc thù của kiểu dữ liệu
Chỗ thứ nhất là stack một vùng ký ức dành lưu trữ dữ liệu chiều dài cố định, chẳng
hạn int chiếm dụng 4 bytes Mỗi chương trình khi đang thi hành đều được cấp phát riêng một stack riêng biệt mà các chương trình khác khơng được mĩ tới Khi một hàm được gọi hàm thi hành thì tất cả các biến cục bộ của hàm được ấn vào stack và khi hàm hồn thành cơng tác thì những biến cục bộ của hàm đều bị tống ra Đây là cách thu hồi khi hàm hết hoạt động
Chỗ thứ hai là heap, một vùng ký ức dùng lưu trữ dữ liệu cĩ bề dày thay đổi và khá
đồ sộ, string chẳng hạn, hoặc dữ liệu cĩ một cuộc sống dài hơn phương thức của một đối tượng chẳng hạn, Thí dụ khi phương thức thể hiện (instantiate) một đối tượng , đối tượng đuợc lưu trữ trên heap, và nĩ khơng bị tống ra khi hàm hồn thành giống như stack, mà ở nguyên tại chỗ và cĩ thể trao cho các phương thức khác thơng qua một qui chiếu Trên C#
heap này được gọi là managed heap, khơn lanh vì heap này cĩ một bộ phận gọi là garbage
collector (GC,dịch vụ hốt rác ) chuyên lo thu hồi ký ức lâu ngày khơng dùng đến (nghĩa là khơng quy chiếu đến)
C# cũng hỗ trợ kiểu con trỏ (pointer type) giống như C++ nhưng ít khi dùng đến và chỉ dùng khi làm việc với đoạn mã unmanaged Đoạn mã unmanaged là đoạn mã đuợc tạo ra ngồi sàn diễn NET, chẳng hạn những đối tượng COM.
Kiểu giá trị được định nghĩa trước (Predefined Value Types)
Kiểu dữ liệu bẩm sinh (The built-in value types) trình bày ban đầu như integer và point numbers, character, và Boolean types
Trang 35integer -32,768:32,767 (-2
15
:215-1) int
System.Int32 32-bit signed
integer
-2,147,483,648:2,147,483,647
(-231:231-1) long System.Int64 64-bit signed
integer
-9,223,372,036,854,775,808: 9,223,372,036,854,775,807 (-263:263-
1) byte System.Byte 8-bit signed
integer 0:255 (0:2
8
-1) ushort System.UInt16 16-bit signed
integer 0:65,535 (0:2
16
-1) uint System.UInt32 32-bit signed
integer 0:4,294,967,295 (0:2
32
-1) ulong System.UInt64 64-bit signed
integer
0:18,446,744,073,709,551,615(0:264
-1) Thí dụ :
long x = 0x12ab;// ghi theo hexa
Float System.Single precision floating- 32-bit
decimal System.Decimal precision decimal 128-bit high
notation
28 ±1.0 × 10-28 to
±7.9 × 1028
Trang 36System.Boolean true or false
Kiểu Character Type:
Name CTS Type Value
char
System.Char Represents a single 16-bit (Unicode) character
Kiểu tham khảo tiền định nghĩa:
C# hỗ trợ hai kiểu dữ liệu được định nghĩa trước:
object System.Object The root type, from which all other types in the CTS
derive (including value types) string System.String Unicode character string
Trang 37Đối tượng kiểu string thường chứa một chuỗi ký tự.Khi khai báo một biến chuỗi sử dụng
từ khoá string giống như sau:
string myString;
Thường thì phải khởi gán một biến chuỗi sử dụng đến một kiểu string :
string myString = "Xin chao" ;
Chuổi được khai báo là một đường dẫn:
string filepath = "C:\\ProCSharp\\First.cs";
Download StringExample
3.5 Caâu leänh ñieàu kieän
Câu lệnh điều kiện
Câu lệnh điều kiện
Câu lệnh điều kiện if :
Cú pháp như sau:
if (condition)
statement(s)
[else
Trang 39Đoạn code trên không giới hạn bao nhiêu else if's trong câu điều kiện
Xem các Thí dụ sau để hiểu rõ thêm về switch:
// assume country and language are of type string
Trang 40C# cung cấp cho chúng ta 4 vòng lặp khác nhau (for, while, do while, và foreach)
cho phép chúng ta thực hiện một đoạn mã lặp lại đến khi đúng điều kiện lặp
Đoạn mã sau sẽ xúât ra tất cả số nguyên từ 0 đến 99:
for (int i = 0; i < 100; i = i+1)
// This loop iterates through rows
for (int i = 0; i < 100; i+=10)
Kết quả được in ra khi chạy chương trình như sau:
Download Loop for
csc NumberTable.cs
Microsoft (R) Visual C# NET Compiler version 7.00.9466
for Microsoft (R) NET Framework version 1.0.3705
Copyright (C) Microsoft Corporation 2001 All rights reserved