TÀI LIỆU

Attributes và Reflection

Science and Technology

Xin được nhắc lại rằng một ứng dụng .NET bao gồm mã chương trình, dữ liệu, metadata. Metadata chính là thông tin về dữ liệu mà ứng dụng sử dụng như kiểu dữ liệu, mã thực thi, assembly,…

Attributes là cơ chế để tạo ra metadata. Ví dụ như chỉ thị cho trình biên dịch, những dữ liệu khác liên quan đến dữ liệu, phương thức, lớp, …

Reflection là quá trình một ứng dụng đọc lại metadata của chính nó để có cách thể hiện, ứng xử thích hợp cho từng người dùng.

Attributes

Một attribute là một đối tượng, trong đối tượng đó chứa một mẩu dữ liệu, mà lập trình viên muốn đính kèm với một phần tử (element) nào đó trong ứng dụng. Phần tử (element) mà lập trình viên muốn đính kèm attribute gọi là mục tiêu (target) của attribute. Ví dụ attribute:

[NoIDispatch]

được đính kèm với một lớp hay một giao diện để nói rằng lớp đích (target class) nên được thừa kế từ giao diện IUnknown chứ không phải thừa kế từ IDispatch.

Attribute mặc định (intrinsic attributes)

Có 2 loại attribute:

  • Attributemcđnh: là attribute được CLR cung cấp sẵn.
  • Attribute do lập trình viên định nghĩa (customattribute)

Đích của Attribute

Mỗi attribute chỉ ảng hưởng đến một đích (target) mà nó khai báo. Đích có thể là lớp, giao diện, phương thức … Bảng sau liệt kê tất cả các đích

Các đích của attribute

Áp dụng Attribute

Lập trình viên áp dụng attribute lên mục tiêu bằng cách đặt attribute trong ngoặc vuông [] liền trước mục tiêu. Ví dụ attribute “Assembly” được áp dụng:

[assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile(“keyfile.snk”)]

Cách sau cũng tương đương với cách trên:

[assembly: AssemblyDelaySign(false), assembly: AssemblyKeyFile(“keyfile.snk”)]

Attribute thường dùng trong lập trình C# là “Serializable”

[serializable] class MySerClass

Attribute trên báo cho compiler biết rằng lớp MySerClasscần được bảo đảm trong việc ghi nội dung, trạng thát xuống dĩa từ hay truyền qua mạng.

Attribute do lập trình viên tạo ra

Lập trình viên hoàn toàn tự do trong việc tạo ra các attribute riêng và đem sử dụng chúng vào nơi nào cảm thấy thích hợp.

Khai báo Attribute tự tạo

Đầu tiên là thừa kế một lớp từ lớp System.Attribute:

Public class XYZ : System.Attribute

Sau đó là báo cho compiler biết attribute này có thể đem áp dụng lên mục tiêu nào.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]

Attribute AttributeUsage”trên có mục tiêu áp dụng là Attribute khác: gọi là meta-attribute.

Đặt tên một attribute

Lập trình viên hoàn toàn tự do trong việc đặt tên cho attribute. Tuy nhiên, compiler của .NET còn có thêm khả năng tự nối thêm chuỗi “Attribute” vào tên. Điều đó có nghĩa là nếu lập trình viên định nghĩa một attribute có tên là “MyBugFix”thì khi tìm kiếm hoặc truy xuất attribute trên, lập trình viên có thể viết tên attribute: MyBugFixhoặc “MyBugFixAttribute”.Nếu một attribute có tên là “MyBugFixAttribute”thì lập trình viên cũng có thể ghi tên attribute là MyBugFixhoặc “MyBugFixAttribute”.

[MyBugFix(123, "Jesse Liberty", "01/01/05", Comment="Off by one")]

Khởi tạo Attribute

Mỗi attribute phải có ít nhất một contructor. Attribute nhận 2 kiểu đối số: kiểu vị trí (positional) và kiểu tên (named).

Trong ví dụ MyBugFix ở phần trước, phần tên và ngày tháng là kiểu vị trí, phần ghi chú (comment) là kiểu tên.

Các đối số kiểu vị trí phải được truyền vào contructor đúng theo thứ tự khai báo. Ví dụ:

public BugFixAttribute(int bugID, string programmer, string date) { this.bugID = bugID; this.programmer = programmer; this.date = date; }

Đối số kiểu tên thì được cài đặt như là properties:

public string Comment { get { return comment; } set { comment = value; } }

Sử dụng Attribute

Một khi đã định nghĩa attribute, lập trình viên sử dụng nó bằng cách đặt nó ngay trước mục tiêu (target) của nó. Ví dụ:

[BugFixAttribute(121,"Jesse Liberty","01/03/05")] BugFixAttribute(107,"Jesse Liberty","01/04/05", Comment="Fixed off by one errors")] public class MyMath

Ví dụ trên áp dụng attribute MyBugFix vào lớp MyMath.

Reflection

Để cho việc lưu attribute trong metadata có ích, cần phải có cơ chế truy xuất chúng vào lúc chạy. Các lớp trong vùng tên (namespace) Reflection, cùng với các lớp trong System.TypeSystem.TypeReference, cung cấp sự hỗ trợ truy xuất metadata.

Reflection là một khái niệm chung cho bất kỳ thao tác nào trong các thao tác sau đây:

  • Xem xét metadata
  • Tìm hiểu kiểu dữ liệu (type discovery): lớp, interface, phương thức, đối số của phương thức, properties, event, field, …
  • Nối kết trễ các phương thức và properties (late binding to methods and properties)
  • Tạo ra một kiểu dữ liệu mới ngay trong lúc thực thi. Lập trình viên có thể định nghĩa một assembly mới ngay lúc chạy, có thể lưu xuống dĩa từ để dùng lại.