C# - C Sharp: Attributes


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Tổng quan

Các Attributes ( thuộc tính ) cung cấp một phương pháp mạnh mẽ để liên kết  siêu dữ liệu ( metadata ) hoặc thông tin khai báo với mã (tập hợp, kiểu, phương thức, thuộc tính, v.v.). Sau khi một Attribute được liên kết với một chương trình, Attribute  đó có thể được truy vấn trong thời gian chạy bằng cách sử dụng một kỹ thuật gọi là Reflection.

Attributes bao gồm

  • Attributes thêm siêu dữ liệu vào chương trình của bạn. Siêu dữ liệu là thông tin về các kiểu (type) được xác định trong một chương trình. Tất cả các tập hợp .NET đều chứa một bộ siêu dữ liệu được chỉ định mô tả các loại và thành viên kiểu được xác định trong tập hợp. Bạn có thể thêm Attributes tùy chỉnh để chỉ định bất kỳ thông tin bổ sung nào được yêu cầu.
  • Bạn có thể áp dụng một hoặc nhiều Attributes cho toàn bộ tập hợp, mô-đun hoặc các phần tử chương trình nhỏ hơn như lớp và thuộc tính (Property).
  • Attributes có thể chấp nhận các đối số giống như các phương thức (method) và thuộc tính (Property) .
  • Chương trình của bạn có thể kiểm tra siêu dữ liệu của chính nó hoặc siêu dữ liệu trong các chương trình khác bằng cách sử dụng Reflection.

Reflection

Reflection cung cấp các đối tượng (thuộc loại Type ) mô tả các assemblies, modules, và types. Bạn có thể sử dụng reflection để tự động tạo một phiên bản của một type, liên kết type đó với một đối tượng hiện có hoặc lấy type từ một đối tượng hiện có và gọi các phương thức của nó hay truy cập các trường và thuộc tính của nó. Nếu bạn đang sử dụng attributes trong mã của mình, thì reflection sẽ cho phép bạn truy cập chúng

Ví dụ

// Sử dụng phương thức GetType() để lấy kiểu dữ liệu của biến
int i = 42;
Type type = i.GetType();
Console.WriteLine(type);

Output sẽ là: System.Int32

// Sử dụng reflection để lấy thông tin của assembly
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);

Output có dạng như: System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e

Chú ý

Từ khóa C# protected và internal  không có ý nghĩa trong Ngôn ngữ trung gian (IL) và không được sử dụng trong API Reflection. Các thuật ngữ tương ứng trong IL là Family và Assembly . Để xác định một  phương thức internal sử dụng reflection, hãy sử dụng thuộc tính IsAssembly . Để xác định một phương thức protected internal, hãy sử dụng IsFamilyOrAssembly.

Sử dụng attributes

Atributes có thể được đặt trên hầu hết mọi khai báo, mặc dù một attribute cụ thể có thể hạn chế các loại khai báo hợp lệ. Trong C#, bạn chỉ định một attribute bằng cách đặt tên của attribute  được đặt trong dấu ngoặc vuông ( []) phía trên phần khai báo thực thể mà attribute đó áp dụng.

Ví dụ về attribute SerializableAttribution được sử dụng để áp dụng một đặc tính cụ thể cho một lớp:

[Serializable]
public class SampleClass
{
    // Các đối tượng của lớp này có thể được Serialize
}

Có thể đặt nhiều thuộc tính trên một khai báo

void MethodA([In][Out] ref double x) { }
void MethodB([Out][In] ref double x) { }
void MethodC([In, Out] ref double x) { }

Một số thuộc tính có thể được chỉ định nhiều lần cho một thực thể nhất định. Một ví dụ về thuộc tính đa dụng như vậy là ConditionalAttribution:

[Conditional("DEBUG"), Conditional("TEST1")]
void TraceMethod()
{
    // ...
}

Ghi chú

Theo quy ước, tất cả các tên thuộc tính đều kết thúc bằng từ "Attribute" để phân biệt chúng với các mục khác trong thư viện .NET. Tuy nhiên, bạn không cần chỉ định hậu tố thuộc tính khi sử dụng thuộc tính trong mã. Ví dụ: [DllImport] tương đương với [DllImportAttribute], nhưng DllImportAttribute là tên thật của thuộc tính trong Thư viện lớp .NET.

Attribute Parameter

Nhiều thuộc tính có các tham số, có thể là vị trí, không tên hoặc được đặt tên. Bất kỳ tham số vị trí nào cũng phải được chỉ định theo một thứ tự nhất định và không thể bỏ qua. Các tham số được đặt tên là tùy chọn và có thể được chỉ định theo bất kỳ thứ tự nào. Các tham số vị trí được chỉ định đầu tiên. Ví dụ: ba thuộc tính này tương đương nhau:

[DllImport("user32.dll")]
[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]
[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

Tham số đầu tiên, tên DLL, có vị trí và luôn đứng đầu; những người khác được đặt tên. Trong trường hợp này, cả hai tham số được đặt tên đều mặc định là sai nên có thể bỏ qua. Các tham số vị trí tương ứng với các tham số của hàm tạo thuộc tính. Các tham số được đặt tên hoặc tùy chọn tương ứng với thuộc tính hoặc trường của thuộc tính. Tham khảo tài liệu của từng thuộc tính để biết thông tin về các giá trị tham số mặc định.

Attribute targets

Target của thuộc tính là thực thể mà thuộc tính đó áp dụng. Ví dụ: một thuộc tính có thể áp dụng cho một lớp, một phương thức cụ thể hoặc toàn bộ tập hợp. Theo mặc định, một thuộc tính sẽ áp dụng cho phần tử theo sau nó. Nhưng bạn cũng có thể xác định rõ ràng, ví dụ: liệu một thuộc tính có được áp dụng cho một phương thức hay cho tham số của nó hay cho giá trị trả về của nó hay không.

Để xác định rõ ràng một target mà thuộc tính sẽ áp dụng, hãy sử dụng cú pháp sau:

[target : attribute-list]

Danh sách các giá trị target có thể được hiển thị trong bảng sau.

Giá trị của mục tiêu Áp dụng cho
assembly Toàn bộ assembly
module Mô-đun trong assembly hiện tại
field Trường trong một lớp(class) hoặc một cấu trúc(struct)
event Event
method Trình truy cập phương thức hoặc get, set của method
param Tham số phương thức hoặc hàm set của tham số
property Property
return Giá trị trả về của một phương thức, bộ chỉ mục thuộc tính hoặc hàm  get của property 
type Struct, class, interface, enum, hoặc delegate

Ví dụ sau đây cho thấy cách áp dụng các thuộc tính cho tập hợp và mô-đun.

using System;
using System.Reflection;
[assembly: AssemblyTitleAttribute("Production assembly 4")]
[module: CLSCompliant(true)]

Ví dụ sau đây cho thấy cách áp dụng các thuộc tính cho các phương thức, tham số phương thức và giá trị trả về của phương thức trong C#.

// mặc định: áp dụng cho method
[ValidatedContract]
int Method1() { return 0; }

// áp dụng cho method
[method: ValidatedContract]
int Method2() { return 0; }

// áp dụng cho tham số
int Method3([ValidatedContract] string contract) { return 0; }

// áp dụng cho giá trị trả về 
[return: ValidatedContract]
int Method4() { return 0; }

Các cách sử dụng phổ biến của attribute

  • Đánh dấu các phương thức bằng cách sử dụng WebMethod thuộc tính trong các dịch vụ Web để chỉ ra rằng phương thức đó có thể gọi được qua giao thức SOAP.
  • Mô tả cách sắp xếp các tham số của phương thức khi tương tác với mã gốc. 
  • Mô tả các thuộc tính COM cho các lớp, phương thức và giao diện.
  • Gọi mã không được quản lý bằng lớp DllImportAttribution .
  • Mô tả tập hợp của bạn về tiêu đề, phiên bản, mô tả hoặc nhãn hiệu.
  • Mô tả các thành viên nào của một lớp cần tuần tự hóa để duy trì sự bền bỉ.
  • Mô tả cách ánh xạ giữa các thành viên lớp và các nút XML để tuần tự hóa XML.
  • Mô tả các yêu cầu bảo mật cho các phương pháp.
  • Chỉ định các đặc điểm được sử dụng để thực thi bảo mật.
  • Kiểm soát tối ưu hóa bằng trình biên dịch đúng lúc (JIT) để mã vẫn dễ dàng gỡ lỗi.
  • Lấy thông tin về người gọi đến một phương thức.
» Tiếp: using
« Trước: Biểu thức nameof
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!