Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.59 MB, 226 trang )
CTS và CLS
Tất cả các kiểu dữ liệu được khai báo dưới sự chỉ đạo của Common Type System (CTS).
CTS định nghĩa một bộ quy tắc mà trình biên địch phải tuân thủ, tham chiếu, sử dụng, và lưu trữ
cả hai kiểu tham khảo và kiểu giá trị. Do đó CTS, các đối tượng được viết bằng các ngôn ngữ
khác nhau có thể được tương tác lẫn nhau.
Tuy nhiên, Không phải tất cả các kiểu đều sử dụng trong tất cả ngôn ngữ lập trình. Để xây dựng
các thành phần có thể truy cập từ tất cả ngôn ngữ .NET , Đặc tả ngôn ngữ chung Common
Language Specification (CLS) nên được sử dụng. Với CLS, Trình biên dịch có thể kiểm tra sự
hợp lệ đoạn code trong đặc tả của CLS .
Nhiều ngôn ngữ hỗ trợ .NET không chỉ hạn chế các tập con tính năng chung, nó được định nghĩa
với CLS; thậm chí với .NET nó vẫn có khả năng tạo các thành phần mà không thể sử dụng từ các
ngôn ngữ khác.
.NET Framework đã được thiết kế với mục tiêu hỗ trợ đa ngôn ngữ. Trong suốt giai đoạn thiết
kế .NET, Microsoft đã mời nhiều nhà sản xuất trình biên dịch để xây dựng .NET languages cho
chính họ. Chính Microsoft phân phối Visual Basic .NET, Managed C++, C#, J#, và JScript.NET.
Thêm vào đó hơn hai mươi ngôn ngữ từ các nhà sản xuất khác nhau như COBOL, Smalltalk,
Perl, và Eiffel. Mỗi loại đều có những thuận lợi riêng biệt và nhiều tính năng khác nhau. Các
trình biên dịch của những ngôn ngữ này đều được mở rộng để hỗ trợ .NET.
Quan trọng
CLS là đặc tả những yêu cầu tối thiểu mà một ngôn ngữ phải hỗ trợ. Có nghĩa là
nếu chúng ta giới hạn các phương thức công cộng (public methods) của chúng ta
cho CLS, thì tất cả các ngôn ngữ đang hỗ trợ .NET có thể sử dụng các lớp của
chúng ta !
Common Type System (CTS)
Common Type System ( còn gọi là Common Type Specification, đặc tả kiểu dữ liệu thông
dụng), có nghĩa là ngôn ngữ trung gian IL (Intermediate Language) xuất hiện với một lô kiểu dữ
liệu bẩm sinh (predefined, hoặc built-in) được định nghĩa rõ ràng. Trong thực tế, những kiểu dữ
liệu này được tổ chức theo một đẳng cấp kiểu (type hierachy), điển hình trong môi trường thiên
đối tượng.
Lý do CTS rất quan trọng là, nếu một lớp được dẫn xuất từ một lớp nào đó hoặc chứa những thể
hiện (instance) của những lớp khác, nó cần biết kiểu dữ liệu mà các lớp khác sử dụng đến. Trong
quá khứ, chính việc thiếu một cơ chế khai báo loại thông tin này là một cản trở cho việc kế thừa
xuyên ngôn ngữ. Loại thông tin này đơn giản không có trong tập tin .EXE chuẩn hoặc DLL.
Một phần nào đó, vấn đề lấy thông tin về kiểu dữ liệu đã được giải quyết thông tin qua
metadate trong assembly. Thí dụ, giả sử bạn đang viết một lớp theo C#, và bạn muốn lớp này
được dẫn xuất từ một lớp được viết theo VB.NET. Muốn làm được điều này, bạn sẽ yêu cầu
trình biên dịch qui chiếu về assembly mà lớp VB.NET đã được khai báo. Lúc này, trình biên
dịch sẽ dùng metadata trên assembly này để lần ra tất cả các phương thức, thuộc tính và vùng
mục tin (field), v.v... liên quan đến lớp VB.NET. Rõ ràng là trình biên dịch cần đến thông tin này
để có thể biên dịch đoạn mã của bạn.
Tuy nhiên, trình biện dịch lại cần đến nhiều thông tin hơn những gì metadata cung cấp. thí dụ,
giả sử một trong những phương thức trên lớp VB.NET được định nghĩa trả về một Integer - là
một trong những kiểu dữ liệu bẩm sinh trên VB.NET. Tuy nhiên, C# lại không có kiểu dữ liệu
mang tên Integer này. Rõ là chúng ta chỉ có thể dẫn xuất từ lớp và sử dụng phương thức này và
sử dung kiểu dữ liệu trả về từ đoạn mã C# nếu trình biên dịch biết làm thế nào ánh xạ (map) kiểu
dữ liệu Integer của VB.NET lên một kiểu dữ liệu nào đó được định nghĩa trên C#.
Điều này có thể thực hiện được vì CTS đã định nghĩa những kiểu dữ liệu bẩm sinh có sẵn trên
Intermediate Language (IL), như vậy tất cả các ngôn ngữ tuân thủ .NET Framework sẽ kết sinh
ra đoạn mã dựa cuối cùng vào những kiểu dữ liệu này. Thí dụ, ta thử xét lại Integer của
VB.NET, hiện là một số nguyên có dấu 32-bit, được ánh xạ lên kiểu dữ liệu Int32 của IL. Như
vậy đây sẽ là kiểu dữ liệu được khai báo trong đoạn cấp mã nguồn, C# dùng từ chốt int để ám
chỉ int32, do đó trình biên dịch sẽ cư xử với phương thức VB.NET xem như hàm sẽ trả về một
int.
Nhìn chung, CTS là một đặc tả hình thức có nhiệm vụ mô tả một kiểu dữ liệu nào đó (lớp, cấu
trúc, giao diện, kiểu dữ liệu bẩm sinh, v.v...) phải được định nghĩa thế nào để CLR có thể chấp
nhận làm việc. Ngoài ra, CTS cũng định nghĩa một số cấu trúc cú pháp (chẳng hạn nạp chồng
các tác từ - overloading operrator) mà một số ngôn ngữ "ăn ý với .NET" (.NET aware language)
có thể chấp nhận hỗ trợ hoặc không. Khi bạn muốn xây dựng những đoạn mã có thể đem sử
dụng bởi tất cả các ngôn ngữ .NET aware, bạn cần tuân thủ các quy tắc của CLS ( ta sẽ xem sau
trong chốc lát) khi trưng ra những kiểu dữ liệu.
Common Language Specification ( CLS, đặc tả ngôn ngữ thông
dụng)
Làm việc "ăn ý" với CTS để bảo đảm suôn sẻ việc hợp tác liên ngôn ngữ. CLS đề ra một số
chuẩn mực mà tất cả các trình biên dịch nhắm vào .NET Framework phải chấp nhận hổ trợ. Có
thể có một người viết trình biên dịch muốn hạn chế khả năng của một trình biên dịch nào đó
bằng cách chỉ hổ trợ một phần nhỏ những tiện nghi mà IL và CTS cung cấp. Việc này không hề
gì miễn là trình biên dịch hổ trợ mọi thứ đã được định nghĩa trong CLS.
Để lấy một thí dụ, CTS định nghĩa một kiểu dữ liệu số nguyên có dấu 32-bit, int32 và không
dấu, uint32. C# nhận biết hai kiểu dữ liệu này là int và uint. Nhưng VB.NET thì chỉ công nhận
độc nhất int32, mang từ chốt integer mà thôi.
Ngoài ra, CLS hoạt động theo hai cách. Trước tiên, có nghĩa là những trình biên dịch riêng rẽ
không nhất thiết phải mạnh, chịu hổ trợ tất cả các chức năng của .NET Framework, đây là một
cách khuyến khích việc phát triển những trình biên dịch đối với ngững ngôn ngữ khác sử dụng
sàn diễn .NET. Thứ đấy, CLS đưa ra một bảo đảm nếu bạn chỉ giới hạn các lớp của bạn vào việc
trưng ra những chức năng chiều ý CLS (CLS-compliant), thì CLS bảo đảm là đoạn mã viết theo
các ngôn ngữ khác có thể sử dụng các lớp của bạn. Thí dụ, nếu bạn muốn đoạn mã của bạn
là CLS-compliant, bạn sẽ không có bất cứ phương thức nào trả về uint32, vì kiểu dữ liệu này
không phải là thành phần của CLS. Nếu bạn muốn, bạn cũng có thể trả về một Uint32, những lúc
ấy không bảo đảm đoạn mã của bạn hoạt động xuyên ngôn ngữ. Nói cách khác, hoàn toàn chấp
nhận khi bạn viết một đoạn mã không CLS-compliant. Nhưng nếu bạn làm thế, thì không chắc gì
đoạn mã biên dich IL của bạn hoàn toàn độc lập về mặt ngôn ngữ (language independent).
CLS là một tập hợp những quy tắc hướng dẫn mô tả một cách chi tiết sống động những tính
năng (feature) tối thiểu và trọn vẹn mà một trình biên dịch .NET aware nào đó phải chấp nhận hổ
trợ để có thể tạo ra đoạn mã chiều ý CLS, và đồng thời có thể được sử dụng theo một cách đồng
nhất giữa các ngôn ngữ theo đuôi sàn diễn .NET. Trong chừng mực nào đó, CLS có thể được
xem như một tập hợp con (subset) của chức năng chọn vẹn được định nghĩa bởi CTS.
CLS bao gồm một tập hợp những qui tắc mà các nhà tạo công cụ phải tuân thủ nếu muốn sản
phẩm của mình làm ra có thể hoạt động không trục trặc trong thế giới .NET. Mỗi qui tắc sẽ mang
một tên (chẳng hạn "CLS rule 6"), và mô tả qui tắc này sẽ ảnh hưởng thế nào đối với người thiết
kế công cụ cũng như đối với người tương tác với công cụ.
Ngoài ra, CLS còn định nghĩa vô số qui tắc khác; chẳng hạn CLS mô tả một ngôn ngữ nào đó
phải biểu diễn thế nào các chuỗi chữ, liệt kê kiểu enumeration phải được biểu diễn thế nào về
mặt nội tại, v.v... Nếu bạn muốn biết chi tiết về CLS, thì mời tham khảo MSDN trên máy của
bạn.
Những yêu cầu của CLS
Chúng ta chỉ thấy hoạt động CLS khi chúng ta đã khoá kế thừa cross-language giữa MC++,
VB.NET, và C#. Cho đến bây giờ chúng ta không cần chú ý đến yêu cầu của CLS khi xây dựng
project. Chúng ta may mắn phương thức chúng ta định nghĩa trong các lớp cơ bản đã có thể gọi
từ các lớp dẫn xuất. Nếu phươnghtức của chúng ta có kiểu dữ liệu System.UInt32 như là thông
số của nó chúng ta không thể sử dụng nó từ VB.NET. Kiểu dữ liệu không tên không có CLScompliant; nó không cần thiết hỗ trợ kiểu dữ liệu này.
Common Language Specification chính xác định nghĩa những yêu cầu để tạo thành phần CLScompliant, với khả năng này nó được sử dụng với các ngôn ngữ .NET khác nhau. Với COM
chúng ta phải chú ý đến yêu cầu đặc tả ngôn ngữ khi thiết kế một thành phần. JScript có yêu cầu
khác với VB6, và điều kiện của VJ++ cũng khác. Trong trường hợp không phải .NET. khi thiết
kế một thành phần nên sử dụng những ngôn ngữ khác nhau chúng ta chỉ phải tạo CLS cho nó,
hoặc CLS_compliant; Nó đảm bảo rằng thành phần này có thể sử dụng từ tất cả ngôn ngữ .NET,
nếu bạn đánh dấu một lớp như CLS, compliant, trình biên dịch có thể báo trước chúng ta về
phương thức non-compliant.
Common Language Runtime (CLR)
Từ ngữ runtime ( vào lúc chạy) ám chỉ một tập hợp những dịch vụ cần thiết để cho thi hành một
đoạn mã nào đó. Mỗi ngôn ngữ đều có riêng cho mình một runtime library hoặc runtime module.
Thí dụ, MFC ( Microsoft Foundation Class) hoạt động cùng với Visua C++ cần kết nối với MFC
runtime library (mfc42.dll), Visua Basic 6.0 thì lại gắn chặt với một hoặc hai runtime module
(msvbvm60.dll), còn Java Virtual Machinee (JVM) như là module runtime.
Với sàn diễn .NET, bộ phận runtime được gọi là Comon Language Runtime (CLR) có hơi
khác với những runtime kể trên: CLR cung cấp một tầng lớp (layer) runtime duy nhất được định
nghĩa rõ ràng và được chia sẻ sử dụng bởi tất cả các ngôn ngữ .NET aware ("ăn ý" với .NET).
CLR gồm hai bộ phận chủ chốt :
Phần thứ nhất, là "cỗ máy" thi hành vào lúc chạy (runtime execution engine), mang tên
mscoree.dll ( tắt chữ Microsoft Core Execution Engine). Khi một assembly được gọi vào thi
hành, thì mscoree.dll được tự động nạp vào, và đến phiên nó nạp assembly cần thiết vào ký ức.
Runtime Execution Engine chịu trách nhiệm thực hiện một số công tác. Trước tiên, nó phải lo
việc giải quyết "vị trí đóng quân" của assembly và tìm ra kiểu dữ liệu yêu cầu ( nghĩa là lớp, giao
diện, cấu trúc, v.v...) thông qua metadata trong assembly. Execution Engine biên dịch IL được
gắn liền dựa theo chỉ thị cụ thể sàn diễn, tiến hành một số kiểm tra an toàn cũng như một số công
việc liên hệ.
Phần thứ hai của CLR là thư viện lớp cơ bản, mang tên mscorlib.dll ( tắt chữ Microsoft Core
Library), chứa vô số công tác lập trình thông dụng. Khi bạn xây dựng .NET Solutions ( giải pháp
.NET) bạn sẽ cần đến nhiều phần thư viện này.
Global Assembly Cache
Global assembly cache là một tên ngụ ý, một nơi lưu trữ (cache) cho toàn bộ các assemblies
sẵn dùng. Hầu hết shared assemblies được cài đặt bên trong cache này, nhưng một vài private
assemblies cũng được tìm thấy ở đây. Nếu một private assembly được biên dịch thành ngôn ngữ
máy sử dụng sinh ra ảnh, mã máy được biên dịch cũng được đưa vào trong cache này.
Nội dung chính:
•
•
Tạo ảnh bẩm sinh (native images) lúc cài đặt
Tổng quan shared assemblies với Global Assembly Cache Viewer và Global Assembly
Cache Utility
Native Image Generator
Với native image generator tiện ích Ngen.exe chúng ta có thể biên dịch mã IL thành ngôn ngữ
máy ngay lúc cài đặt. Bằng cách này chương trình khởi đầu nhanh hơn vì sự biên dịch trong quá
trình chạy là không cần thiết. Tiện ích ngen cài đặt native image trong native image cache, nó là
một phần của global assembly cache.
Lưu ý:
Tạo native images với ngen chỉ cần thiết nếu native images được tạo cho tất cả
assemblies dùng bởi ứng dụng. nếu không trình biên dịch JIT đã phải bắt đầu một
cách không hệ thống.
Với ngen myassembly, chúng ta có thể biên dịch mã MSIL thành mã máy, và cài đặt nó vào
bên trong nơi lưu native image . Điều này nên được thực hiện từ chương trình cài đặt nếu chúng
ta muốn đặt assembly trong native image cache.
Lưu ý:
Sau khi biên dịch assembly thành mã máy bạn không thể huỷ assembly ban đầu với
mã MSIL bởi bì metadata vẫn còn cần đến và nếu bảo vệ thay đổi trên hệ thống mã
máy sẽ được xây dưng lại.
Với ngen chúng ta cũng hiển thị tất cả assemblies từ native image cache bằng cách chọn
option /show. Nếu chúng ta thêm tên assembly thì vào /show option chúng ta lấy thông tin về
phiên bản đã cài đặt của assembly này:
Global Assembly Cache Viewer
GAC Viewer được hiển thị sử dụng shfusion.dll, Nó là một tiện ích của Windows (Windows shell extension )để hiển thị và chế
tác các nội dung của cache. Windows shell extension là một COM DLL nó kết hợp với Windows explorer. Bạn phải mở explorer
và dùng
Hình sau là GAC viewer: