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

Miền ứng dụng ,cơ chế phản chiếu và siêu dữ liệu phần 3

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 (175.14 KB, 8 trang )

1.1
Giải phóng assembly và miền ứng dụng
V
V


Bạn cần giải phóng các assembly hay các miền ứng dụng lúc thực thi.
#
#


Không có cách nào để giải phóng các assembly riêng lẻ. Bạn có thể giải phóng
toàn bộ một miền ứng dụng bằng phương thức tĩnh AppDomain.Unload, đồng
thời với việc giải phóng miền ứng dụng là tất cả các assembly đã được nạp vào
miền ứng dụng đó cũng được giải phóng.
Cách duy nhất để giải phóng một assembly là giải phóng cả miền ứng dụng mà nó đã
được nạp vào. Đáng ti
ếc, việc giải phóng một miền ứng dụng cũng sẽ giải phóng luôn tất
cả các assembly đã được nạp vào đó. Đây là một giới hạn yêu cầu bạn phải tổ chức và
quản lý tốt cấu trúc miền ứng dụng và assembly.
Khi giải phóng một miền ứng dụng bằng phương thức tĩnh AppDomain.Unload, bạn cần
truyền cho nó một tham chiếu AppDomain đến miền ứng dụ
ng cần giải phóng. Bạn
không thể giải phóng miền ứng dụng mặc định do CLR tạo lúc startup. Đoạn mã dưới đây
trình bày cách sử dụng phương thức Unload.
// Tạo một miền ứng dụng mới.
AppDomain newDomain = AppDomain.CreateDomain("New Domain");

// Nạp assembly vào miền ứng dụng mày.
§


// Giải phóng miền ứng dụng.
AppDomain.Unload(newDomain);
Phương thức Unload chặn các tiểu trình mới đi vào miền ứng dụng được chỉ định và gọi
phương thức Thread.Abort trên tất cả các tiểu trình hiện đang chạy trong miền ứng dụng
này. Nếu tiểu trình gọi phương thức Unload hiện đang chạy trong miền ứng dụng cần giải
phóng thì một tiểu trình khác sẽ được khởi chạy để thực hiện quá trình giải phóng. Nếu
có v
ấn đề trong việc giải phóng miền ứng dụng, ngoại lệ
System.CannotUnloadAppDomainException sẽ bị ném bởi tiểu trình thực hiện quá trình
giải phóng.
Trong khi miền ứng dụng đang được giải phóng, CLR gọi thực thi các phương thức giải
phóng của tất cả các đối tượng trong miền ứng dụng. Tùy thuộc vào số lượng đối tượng
và bản chất của các phương thức giải phóng mà quá trình này có thể
mất một khoảng thời
gian nào đó. Phương thức AppDomain.IsFinalizingForUnload trả về true nếu miền ứng
dụng đang được giải phóng và CLR đã bắt đầu giải phóng các đối tượng trong đó; ngược
lại, trả về false.
1.2
Truy xuất thông tin Type
V
V


Bạn muốn thu lấy đối tượng System.Type mô tả một kiểu dữ liệu nhất định.
#
#


Sử dụng một trong các cách sau:
• Toán tử typeof

• Phương thức tĩnh GetType của lớp System.Type
• Phương thức GetType thuộc một thể hiện của kiểu
• Phương thức GetNestedType hay GetNestedTypes của lớp Type
• Phương thức GetType hay GetTypes của lớp Assembly
• Phương thức GetType, GetTypes, hay FindTypes của lớp System.Reflection.
Module
Đối tượng Type cung cấp một điểm khởi đầu để làm việc với các kiể
u dữ liệu bằng cơ
chế phản chiếu. Một đối tượng Type cho phép bạn kiểm tra siêu dữ liệu của kiểu, thu lấy
các thành viên của kiểu, và tạo các đối tượng của kiểu. Do tầm quan trọng của nó, .NET
Framework cung cấp nhiều cơ chế để lấy tham chiếu đến các đối tượng Type.
Phương pháp hiệu quả nhất để thu lấy đối tượng Type cho một kiể
u cụ thể là sử dụng
toán tử typeof:
System.Type t1 = typeof(System.Text.StringBuilder);
Tên kiểu không được đặt trong dấu nháy kép và phải khả phân giải đối với trình biên
dịch. Vì tham chiếu được phân giải lúc biên dịch nên assembly chứa kiểu này trở thành
phần phụ thuộc tĩnh của assembly và sẽ được liệt kê như thế trong assembly manifest của
bạn.
Một cách khác là sử dụng phương thức tĩnh Type.GetType, nhận vào một chuỗi chứa tên
kiểu. Vì sử
dụng chuỗi để chỉ định kiểu nên bạn có thể thay đổi nó lúc thực thi, điều này
mở ra cánh cửa đến với thế giới lập trình động bằng cơ chế phản chiếu (xem mục 3.12).
Nếu bạn chỉ định tên kiểu, bộ thực thi phải tìm kiểu này trong một assembly đã được nạp.
Bạn cũng có thể chỉ định một tên kiểu theo tiêu chuẩn assembly (tham khảo tài liệ
u .NET
Framework SDK về phương thức Type.GetType để biết cách kết cấu tên kiểu theo tiêu
chuẩn assembly). Các lệnh sau trình bày cách sử dụng phương thức GetType:
// Có phân biệt chữ hoa-thường, trả về null nếu không tìm thấy.
Type t2 = Type.GetType("System.String");


// Có phân biệt chữ hoa-thường,
// ném ngoại lệ TypeLoadException nếu không tìm thấy.
Type t3 = Type.GetType("System.String", true);

// Không phân biệt chữ hoa-thường,
// ném ngoại lệ TypeLoadException nếu không tìm thấy.
Type t4 = Type.GetType("system.string", true, true);

// Tên kiểu theo tiêu chuẩn assembly.
Type t5 = Type.GetType("System.Data.DataSet,System.Data," +
"Version=1.0.5000.0,Culture=neutral,
PublicKeyToken=b77a5c561934e089");
Để thu lấy đối tượng Type mô tả kiểu của một đối tượng hiện có, hãy sử dụng phương
thức GetType, được hiện thực bởi Object và được thừa kế bởi tất cả các kiểu dữ liệu.
Dưới đây là một ví dụ:
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Type t6 = sb.GetType();
Bảng 3.2 tóm tắt các phương thức khác cũng cung cấp khả năng truy xuất đối tượng
Type.

Bảng 3.2 Các phương thức trả về đối tượng Type
Phương thức Mô tả
Type.GetNestedType
Lấy đối tượng Type mô tả một kiểu lồng bên trong
đối tượng Type hiện có
Type.GetNestedTypes
Lấy một mảng các đối tượng Type mô tả các kiểu
lồng bên trong đối tượng Type hiện có
Assembly.GetType

Lấy đối tượng Type mô tả một kiểu được khai báo
bên trong assembly
Assembly.GetTypes
Lấy một mảng các đối tượng Type mô tả các kiểu
được khai báo bên trong assembly
Module.GetType
Lấy đối tượng Type mô tả một kiểu được khai báo
bên trong module
Module.GetTypes
Lấy một mảng các đối tượng Type mô tả các kiểu
được khai báo bên trong module
Module.FindTypes
Lấy một mảng đã được lọc, chứa các đối tượng
Type mô tả các kiểu được khai báo bên trong
module—các kiểu này được lọc bằng một delegate
(xác định xem mỗi Type có xuất hiện trong mảng
đích hay không)
1.3
Kiểm tra kiểu của một đối tượng
V
V


Bạn muốn kiểm tra kiểu của một đối tượng.
#
#


Sử dụng phương thức thừa kế Object.GetType để thu lấy Type cho đối tượng
này. Trong vài trường hợp, bạn cũng có thể sử dụng toán tử is và as để kiểm

tra kiểu của một đối tượng.
Tất cả các kiểu dữ liệu đều thừa kế phương thức GetType từ lớp cơ sở Object. Như đã
được thảo luận trong mục 3.10, phương thức này trả về
một tham chiếu Type mô tả kiểu
của đối tượng. Bộ thực thi duy trì một đối tượng Type cho mỗi kiểu được nạp và tất cả
các tham chiếu cho kiểu này cùng chỉ đến đối tượng này. Điều này nghĩa là bạn có thể so
sánh hai tham chiếu kiểu một cách hiệu quả. Ví dụ dưới đây trình bày cách kiểm tra một
đối tượng có phải là System.IO.StringReader hay không:
// Tạo một StringReader để thử nghiệm.
Object someObject =
new StringReader("This is a StringReader");

// Kiểm tra xem someObject có phải là một StringReader hay không
// bằng cách thu lấy và so sánh tham chiếu Type (sử dụng toán tử typeof).
if (typeof(System.IO.StringReader) == someObject.GetType()) {
// Làm gì đó.
§
}
C# cung cấp toán tử is để thực hiện nhanh việc kiểm tra như trên. Ngoài ra, is sẽ trả về
true nếu đối tượng cần kiểm tra dẫn xuất từ lớp được chỉ định. Đoạn mã dưới đây kiểm
tra xem someObject là một thể hiện của System.IO.TextReader, hay một lớp dẫn xuất từ
TextReader (như StringReader):
// Kiểm tra xem someObject là TextReader,
// hay dẫn xuất từ TextReader bằng toán tử is.
if (someObject is System.IO.TextReader) {
// Làm gì đó.
§
}
Cả hai cách này đều đòi hỏi kiểu dùng với toán tử typeof và is phải là kiểu đã biết và khả
phân giải lúc biên dịch. Một cách khác linh hoạt hơn (nhưng chậm hơn) là sử dụng

phương thức Type.GetType để trả về một tham chiếu Type cho kiểu được chỉ định. Tham
chiếu Type không được phân giải cho đến khi thực thi, việc này ảnh hưởng đến hiệu
năng, nhưng cho phép bạn thay đổi phép so sánh kiểu lúc th
ực thi dựa trên giá trị của một
chuỗi. Phương thức IsType dưới đây sẽ trả về true nếu đối tượng thuộc kiểu được chỉ
định và sử dụng phương thức Type.IsSubclassOf để kiểm tra đối tượng này có phải là
một lớp con của kiểu được chỉ định hay không.
public static bool IsType(object obj, string type) {

Type t = Type.GetType(type, true, true);

return t == obj.GetType() || obj.GetType().IsSubclassOf(t);
}
Cuối cùng, bạn có thể sử dụng toán tử as để ép bất kỳ đối tượng nào sang kiểu được chỉ
định. Nếu đối tượng không thể bị ép sang kiểu được chỉ định, toán tử as sẽ trả về null.
Điều này cho phép bạn thực hiện các phép ép kiểu an toàn (safe cast), nhưng kiểu được
so sánh phải là khả phân giải lúc thực thi. Dưới đây là một ví dụ:
// Sử dụng toán tử as để thực hiện một phép ép kiểu an toàn.
StringReader reader = someObject as System.IO.StringReader;
if (reader != null) {
// Làm gì đó.
§
}
Í
Phương thức tĩnh GetUnderlyingType của lớp System.Enum cho phép bạn thu
lấy kiểu thực sự của một kiểu liệt kê.
1.4
Tạo một đối tượng bằng cơ chế phản chiếu
V
V



Bạn cần tạo một đối tượng bằng cơ chế phản chiếu.
#
#


Thu lấy đối tượng Type mô tả kiểu của đối tượng cần tạo, gọi phương thức
GetConstructor của nó để có được đối tượng
System.Reflection.ConstructorInfo mô tả phương thức khởi dựng cần dùng,
sau đó thực thi phương thức ConstructorInfo.Invoke.
Bước đầu tiên trong việc tạo một đối tượng bằng cơ chế phản chiếu là thu lấy đối tượng
Type mô tả kiểu của đối tượ
ng cần tạo (xem mục 3.10 để biết thêm chi tiết). Khi có được
đối tượng Type, hãy gọi phương thức GetConstructor để thu lấy đối tượng
ConstructorInfo mô tả một trong các phương thức khởi dựng của kiểu này. Dạng thức
thông dụng nhất của phương thức GetConstructor là nhận một mảng Type làm đối số, và
trả về đối tượng ConstructorInfo mô tả phương thức khởi dựng nhận các đối số đượ
c chỉ
định trong mảng Type. Để thu lấy đối tượng ConstructorInfo mô tả phương thức khởi
dựng mặc định (không có đối số), bạn hãy truyền cho phương thức GetConstructor một
mảng Type rỗng (sử dụng trường tĩnh Type.EmptyTypes); đừng sử dụng null, nếu không
GetConstructor sẽ ném ngoại lệ System.ArgumentNullException. Nếu GetConstructor
không tìm thấy phương thức khởi dựng nào có chữ ký phù hợp với các đối số được chỉ
định thì nó s
ẽ trả về null.
Môt khi đã có đối tượng ConstructorInfo như mong muốn, hãy gọi phương thức Invoke
của nó. Bạn phải cung cấp một mảng chứa các đối số mà bạn muốn truyền cho phương

×