Attributes trong C#

0
429

Attribute là một thẻ khai báo được sử dụng để truyền tải thông tin thời gian chạy về các hành vi của các yếu tố khác nhau như lớp, phương pháp, cấu trúc, enumerators, assemblies,.. vv trong chương trình của bạn. Bạn có thể thêm thông tin khai báo một chương trình bằng cách sử dụng một Attribute. Một thẻ khai báo được mô tả bằng dấu ngoặc vuông ([]) .

Attribute được sử dụng để thêm siêu dữ liệu, chẳng hạn như chỉ dẫn của trình biên dịch và các thông tin khác như nhận xét, mô tả, phương thức và các lớp cho một chương trình. Net Framework cung cấp hai loại Attribute: attribute được xác định trước và attribute được xây dựng tùy chỉnh.

Xác định một attribute

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

[attribute(tham_so_vi_tri, ten_tham_so = value, ...)]
element

Tên của attribute và giá trị của nó được đặt trong các dấu ngoặc vuông, đứng trước các yếu tố mà attribute được áp dụng. Tham số vị trí chỉ định các thông tin cần thiết và tham số tên chỉ định các thông tin tùy chọn.

Attribute xác định trước

Net Framework cung cấp ba attribute được xác định trước:

  • AttributeUsage
  • Conditional
  • Obsolete

AttributeUsage

AttributeUsage mô tả cách một lớp attribute tùy chỉnh có thể được sử dụng. Nó chỉ rõ các loại loại items mà attribute có thể được áp dụng.

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

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

Trong đó,

  • Thông số validon quy định các yếu tố ngôn ngữ mà attribute có thể đặt. Nó là sự kết hợp của các giá trị của một AttributeTargets điều tra viên. Giá trị mặc định là AttributeTargets.All.
  • Thông số cho phép cung cấp nhiều (tùy chọn) giá trị cho thuộc tính attribute là AllowMultiple, có giá trị là một giá trị Boolean. Nếu giá trị là true, attribute này là đa dụng. Mặc định là false (đơn dụng).
  • Thông số inherited cung cấp giá trị Boolean  cho các thuộc tính của attribute này. Nếu đó là true, attribute được thừa kế bởi các lớp dẫn xuất. Giá trị mặc định là false (không được thừa kế).

Ví dụ:

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

Conditional

Attribute được xác định trước này đánh dấu một phương pháp có điều kiện mà sự thực thi phụ thuộc vào một định danh tiền xử lý cụ thể.

Nó tạo ra biên soạn có điều kiện khi gọi phương thức, tùy thuộc vào giá trị quy định như Debug or Trace. Ví dụ, nó sẽ hiển thị các giá trị của các biến trong khi Debug một mã

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

[Conditional(
   conditionalSymbol
)]

Ví dụ như:

[Conditional("DEBUG")]

Ví dụ sau đây cho thấy attribute như thế nào:

#define DEBUG
using System;
using System.Diagnostics;

public class Myclass
{
   [Conditional("DEBUG")]
   public static void Message(string msg)
   {
      Console.WriteLine(msg);
   }
}

class Test
{
   static void function1()
   {
      Myclass.Message("Trong hàm 1.");
      function2();
   }
   static void function2()
   {
      Myclass.Message("Trong hàm 2.");
   }
   
   public static void Main()
   {
      Myclass.Message("Trong hàm main.");
      function1();
      Console.ReadKey();
   }
}

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra các kết quả như sau:

Trong hàm main
Trong ham 1
Trong ham 2

Obsolete

Attribute được xác định trước này đánh dấu một thực thể chương trình mà không nên sử dụng. Nó cho phép bạn thông báo cho trình biên dịch để loại bỏ một phần tử mục tiêu 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 các phương thức cũ trong lớp, bạn có thể đánh dấu nó như là bỏ qua bằng cách hiển thị các phương thức mới nên được sử dụng, thay vì phương thức cũ.

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

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

Trong đó,

  • Thông số message, là một chuỗi mô tả lý do tại sao các mục lỗi thời và những gì để sử dụng thay thế.
  • Thông số iserror, là một giá trị Boolean. Nếu giá trị của nó là true, trình biên dịch xử lý với việc sử dụng các item như là một lỗi. Giá trị mặc định là sai (biên dịch tạo ra một cảnh báo).

Chương trình sau đây chứng tỏ điều này:

using System;

public class MyClass
{
   [Obsolete("Don't use OldMethod, use NewMethod instead", true)]
   static void OldMethod()
   {
      Console.WriteLine("Day la phuong thuc cu");
   }
   static void NewMethod()
   {
      Console.WriteLine("Day la phuong thuc moi"); 
   }
   public static void Main()
   {
      OldMethod();
   }
}

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

 Don't use OldMethod, use NewMethod instead

Tạo attribute tùy chỉnh

Net Framework cho phép tạo ra các attribute tùy chỉnh mà có thể được sử dụng để lưu trữ thông tin khai báo và có thể được lấy tại thời gian chạy. Thông tin này có thể liên quan đến bất kỳ yếu tố mục tiêu phụ thuộc vào các tiêu chuẩn thiết kế và nhu cầu ứng dụng.

Tạo và sử dụng các attribute tùy chỉnh bao gồm bốn bước:

  • Khai báo một attribute tùy chỉnh
  • Xây dựng attribute tùy chỉnh
  • Áp dụng attribute tùy chỉnh trên một yếu tố chương trình mục tiêu
  • Truy cập attribute thông qua Reflection

Bước cuối liên quan đến việc viết một chương trình đơn giản để đọc qua các siêu dữ liệu để tìm giá trị khác nhau. Siêu dữ liệu là dữ liệu về 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 reflections để truy cập attribute tại thời gian chạy. Điều này chúng ta sẽ thảo luận trong topic tiếp theo.

Khai báo một attribute tùy chỉnh

Một attribute tùy chỉnh mới sẽ được dẫn xuất từ lớp System.Attribute. Ví dụ,

//một attribute tùy chỉnh BugFix được giao 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ước, chúng ta đã khai báo một attribute tùy chỉnh tên DeBugInfo.

Xây dựng attribute tùy chỉnh

Chúng ta hãy xây dựng một attribute tùy chỉnh tên DeBugInfo, trong đó lưu trữ các thông tin thu được bằng cách gỡ lỗi chương trình. Hãy để nó lưu trữ các thông tin sau:

  • Các mã số cho các lỗi
  • Tên của các developer đã xác định được các lỗi
  • Ngày xem cuối cùng của mã
  • Một thông báo chuỗi để lưu trữ các nhận xét của developer

Lớp DeBugInfo có ba đặc tính riêng để lưu trữ ba thông tin đầu tiên và một thuộc tính chung để lưu trữ các thông báo. Do đó số lượng lỗi, tên nhà phát triển, và ngày xem lại là các tham số vị trí của lớp DeBugInfo và thông báo là một tham số tùy chọn hoặc đặt tên.

Mỗi attribute phải có ít nhất một constructor. Các thông số vị trí cần được thông qua thông qua constructor. Các mã sau đây cho thấy lớp DeBugInfo:

//một attribute tùy chỉnh BugFix được giao 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
{
   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;
      }
   }
}

Áp dụng các attribute tùy chỉnh

Các attribute được áp dụng bằng cách đặt nó ngay lập tức trước mục tiêu của nó:

[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle
{
   //Các thanh viên
   protected double length;
   protected double width;
   public Rectangle(double l, double w)
   {
      length = l;
      width = w;
   }
   [DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")]
   
   public double GetArea()
   {
      return length * width;
   }
   [DeBugInfo(56, "Zara Ali", "19/10/2012")]
   
   public void Display()
   {
      Console.WriteLine("Length: {0}", length);
      Console.WriteLine("Width: {0}", width);
      Console.WriteLine("Area: {0}", GetArea());
   }
}

Trong topic tiếp theo, chúng ta lấy thông tin attribute bằng cách sử dụng đối tượng của lớp Reflection.

Chúc bạn thành công!

This site uses Akismet to reduce spam. Learn how your comment data is processed.