Attribute trong C#

Thuộc tính (attribute) trong C#, là một thẻ khai báo, được sử dụng để truyền thông tin tới runtime về các hành vi của các phần tử khác nhau như các lớp, phương thức, cấu trúc, enum, assembly… trong chương trình của bạn. Bạn có thể thêm thông tin khai báo vào chương trình bằng cách sử dụng attribute. Một thẻ khai báo được mô tả bởi các dấu ngoặc vuông ([]) đặt bên trên phần tử mà nó được sử dụng cho.

Các Attribute được sử dụng để thêm metadata, ví dụ như chỉ lệnh biên dịch và thông tin khác như comment, mô tả, phương thức và các lớp vào một chương trình. .Net Framework cung cấp hai kiểu attribute: thuộc tính được định nghĩa trước (pre-defined attribute) và thuộc tính tùy chỉnh (custom built attribute).

Xác định một Attribute trong C#

Cú pháp để xác định một Attribute trong C# như sau:

[attribute(positional_parameter, name_parameter = giá_trị, ...)] element

Tên của attribute và giá trị của nó được xác định bên trong dấu ngoặc vuông, ở trước phần tử mà attribute được áp dụng cho positional_parameter xác định thông tin thiết yếu và name_parameter xác định thông tin tùy chọn.

Attribute được định nghĩa trước trong C#

.Net Framework cung cấp 3 Attribute được định nghĩa trước:

  • AttributeUsage
  • Conditional
  • Obsolete

AttributeUsage trong C#

AttributeUsage mô tả cách một lớp attribute tùy chỉnh có thể được sử dụng. Nó xác định kiểu của các item, mà từ đó attribute có thể áp dụng cho.

Cú pháp để xác định attribute này trong C# như sau:

[AttributeUsage( validon, AllowMultiple=allowmultiple, Inherited=inherited )]

Trong đó:

  • validon: xác định các phần tử ngôn ngữ mà attribute có thể được đặt. Nó là tổ hợp giá trị của một AttributeTargets enumerator. Giá trị mặc định là AttributeTargets.All.
  • allowmultiple (tùy ý): cung cấp giá trị cho đặc tính AllowMultiple của attribute này, một giá trị Boolean. Nếu điều này là true, attribute là multiuse (đa dụng). Giá trị mặc định là false (tức là single-use - chỉ dùng một lần).
  • inherited (tùy ý): cung cấp giá trị cho đặc tính Inherited của attribute này, một giá trị Boolean. Nếu nó là true, attribute được kế thừa bởi các lớp dẫn xuất. Giá trị mặc định là false (không được kế thừa).

Ví dụ:

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

Conditional trong C#

Attribute Conditional đánh dấu một phương thức có điều kiện mà sự thực thi của nó phụ thuộc vào một định danh tiền xử lý được chỉ định.

Nó gây ra việc biên dịch có điều kiện của các lời gọi phương thức, tùy thuộc vào giá trị đã cho, như Debug hoặc Trace. Ví dụ, nó hiển thị giá trị của các biến trong khi debug một code.

Cú pháp để xác định attribute này trong C# như sau:

[Conditional( conditionalSymbol )]

Ví dụ:

[Conditional("DEBUG")]

Sau đây là ví dụ minh họa Conditional trong C#: 

#define DEBUG using System; using System.Diagnostics; public class QuanTriMangCom { [Conditional("DEBUG")] public static void Message(string msg) { Console.WriteLine(msg); } } class Test { static void function1() { QuanTriMangCom.Message("Trong hàm 1."); function2(); } static void function2() { QuanTriMangCom.Message("Trong hàm 2."); } public static void Main() { QuanTriMangCom.Message("Trong hàm Main."); function1(); Console.ReadKey(); } }

Sử dụng lệnh Console.ReadKey(); để nhìn kết quả một cách rõ ràng hơn.

Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau:

Trong hàm Main
Trong hàm 1.
Trong hàm 2.

Obsolete trong C#

Trong C#, Obsolote đánh dấu một thực thể chương trình mà không nên được sử dụng. Nó cho bạn thông báo với trình biên dịch để loại bỏ một phần tử target cụ thể. Ví dụ, khi một phương thức mới đang được sử dụng trong một lớp và nếu bạn vẫn muốn giữ lại phương thức cũ trong lớp này, bạn có thể đánh dấu nó là obsolete (lỗi thời) bằng việc hiển thị một thông báo là phương thức mới sẽ được sử dụng, thay cho phương thức cũ.

Cú pháp để xác định Attribute này trong C# là như sau:

[Obsolete( message )] [Obsolete( message, iserror )]

Trong đó:

message là một chuỗi mô tả lý do tại sao item là obsolete và cái gì được sử dụng thay cho nó.

iserror là một giá trị Boolean. Nếu giá trị của nó là true, trình biên dịch sẽ coi việc sử dụng item này là một lỗi. Giá trị mặc định là false (tức là trình biên dịch sẽ tạo ra cảnh báo).

Ví dụ sau minh họa obsolete trong C#:

using System; public class QuanTriMangCom { [Obsolete("Đừng sử dụng QTM1, hãy sử dụng QTM2", true)] static void QTM1() { Console.WriteLine("Đây là phương thức cũ"); } static void QTM2() { Console.WriteLine("Đây là phương thức mới"); } public static void Main() { QTM1(); } } 

Khi bạn cố gắng biên dịch chương trình trên, trình biên dịch sẽ đưa ra một thông báo lỗi:

Compilation failed: 1 error(s), 0 warnings
main.cs(13,7): error CS0619: `QuanTriMangCom.QTM1()' is obsolete: `Đừng sử dụng QTM1, hãy sử dụng QTM2'

Tạo Custom Attribute trong C#

Còn gọi là attribute tùy biến hay attribute do người dùng tự định nghĩa. .Net Framework cho phép tạo các Custom Attribute mà có thể được sử dụng để lưu trữ thông tin khai báo và có thể được thu nhận tại runtime. Thông tin này có thể liên quan đến bất kỳ yếu tố mục tiêu nào tùy thuộc vào các tiêu chí thiết kế và yêu cầu ứng dụng.

Tạo và sử dụng Custom Attribute trong C# bao gồm 4 bước sau:

  • Khai báo một Custom Attribute
  • Xây dựng Custom Attribute
  • Áp dụng Custom Attribute trên một phần tử chương trình mục tiêu
  • Truy cập các Attribute thông qua Reflection

Bước cuối cùng liên quan tới việc viết một chương trình đơn giản để đọc qua metadata để tìm ra các notation khác nhau. Metadata là dữ liệu hoặc thông tin được sử dụng để mô tả dữ liệu khác. Chương trình này nên sử dụng các Reflection để truy cập các attribute tại runtime. Chúng ta sẽ nói chi tiết hơn về vấn đề này trong bài tới.

Bước 1: Khai báo một Custom Attribute trong C#

Một Custom Attribute mới nên được dẫn xuất từ lớp System.Attribute trong C#. Ví dụ:

//Thuộc tính tùy chính BugFix được gán cho lớp và thành viên của nó. [AttributeUsage(
AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute

Trong code trên, chúng ta đã khai báo một Custom Attribute là DeBugInfo.

Bước 2: Xây dựng Custom Attribute trong C#

Chúng ta cùng xây dựng Custom Attribute có tên là DeBugInfo, lưu trữ thông tin thu được bởi việc debug bất kỳ chương trình nào. Nó sẽ lưu trữ thông tin sau:

  • Mã số của lỗi
  • Tên của nhà phát triển đã xác định được lỗi
  • Ngày review cuối cùng của code đó
  • Một thông báo dạng chuỗi để lưu trữ nhận xét của lập trình viên

Lớp DeBugInfo có 3 đặc tính private để lưu trữ 3 thông tin đầu tiên và một đặc tính public để lưu trữ thông báo. Vì thế, mã số của lỗi, tên nhà phá triển, và ngày review là các positional_parameter tương ứng của lớp DeBugInfo và thông báo name_parameter.

Mỗi attribute phải có ít nhất một constructor. Các positional_parameter tương ứng nên được truyền thông qua constructor đó. Ví dụ sau minh họa lớp DeBugInfo trên:

//Custom attribute BugFix được gán cho các lớp và thành viên của nó.
[AttributeUsage( AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] public class DeBugInfo : System.Attribute { private int bugNo; private string developer; private string lastReview; public string message; public DeBugInfo(int bg, string dev, string d) { this.bugNo = bg; this.developer = dev; this.lastReview = d; } public int BugNo { get { return bugNo; } } public string Developer { get { return developer; } } public string LastReview { get { return lastReview; } } public string Message { get { return message; } set { message = value; } } }

Bước 3: Áp dụng Custom Attribute trong C#

Custom Attribute trong C# được áp dụng bằng việc đặt nó ngay trước target của nó:

[DeBugInfo(45, "Nguyễn Huy", "03/09/2017", Message = "Kiểu trả về không hợp lệ")] [DeBugInfo(49, "Hà Minh", "09/11/2017", Message = "Biến chưa được sử dụng")] class Rectangle { //các biến thành viên protected double dai; protected double rong; public Rectangle(double d, double r) { dai = d; rong = r; } [DeBugInfo(55, "Nguyễn Huy", "03/09/2017", Message = "Kiểu trả về không hợp lệ")] public double tinhS() { return dai * rong; } [DeBugInfo(56, "Hà Minh", "09/11/2017")] public void Display() { Console.WriteLine("Chiều dài: {0}", dai); Console.WriteLine("Chiều rộng: {0}", rong); Console.WriteLine("Diện tích: {0}", tinhS()); } }

Trong chương tới, chúng ta thu hồi thông tin Attribute bởi sử dụng một đối tượng lớp Reflection trong C#.

 Theo tutorialspoint

Bài trước: File I/O trong C#

Bài tiếp: Reflection trong C#

Thứ Bảy, 28/07/2018 18:15
31 👨 737