Tải bản đầy đủ (.pdf) (11 trang)

Tìm hiểu về Intermediate Language – Phần 1 pps

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 (135.29 KB, 11 trang )

Tìm hiểu về Intermediate
Language – Phần 1

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.
Bê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.
Trong 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:
 Language Interoperability
 Garbage Collection
 Security
 Application Domains
Hãy tìm hiểu xem tại sao kiểu dữ liệu mạnh lại là một trong những đặc tính
quan trọng của .NET.
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 cá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:
Kiểu Giải thích
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.
Kiểu Giải thích
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)
Common 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.

×