Reflection trong C#

Các đối tượng Reflection được sử dụng để thu được thông tin kiểu tại runtime. Các lớp này cung cấp quyền truy cập tới metadata của chương trình đang chạy trong namespace System.Reflection trong C#.

Trong C# Namespace System.Reflection chứa các lớp mà cho phép bạn thu được thông tin về ứng dụng và để thêm các kiểu, giá trị, và các đối tượng một cách động tới Application.

Các ứng dụng của Reflection

Reflection có các ứng dụng sau:

  • Cho phép quan sát thông tin attribute tại runtime.
  • Cho phép kiểm tra các kiểu khác nhau trong một Assembly và khởi tạo các kiểu này.
  • Cho phép Late Binding tới các phương thức và các thuộc tính.
  • Cho phép tạo các kiểu mới tại runtime và sau đó thực hiện một số tác vụ sử dụng những kiểu này.

Xem Metadata trong C#

Chúng ta đã đề cập trong bài trước rằng với việc sử dụng Reflection, bạn có thể xem thông tin attribute.

Đối tượng MemberInfo của lớp System.Reflection trong C# cần được khởi tạo để phát hiện ra các attribute được liên kết với một lớp. Để làm điều này, bạn định nghĩa một đối tượng của lớp target, như:

System.Reflection.MemberInfo info = typeof(MyClass);

Ví dụ sau minh họa điều này: tạo 3 lớp có tên lần lượt là HelpAttribute, MyClass, Tester như sau:

using System; namespace VdMetadata { [AttributeUsage(AttributeTargets.All)] public class HelpAttribute : System.Attribute { public readonly string Url; public string Topic // Topic la mot name parameter 
{ get { return topic; } set { topic = value; } } public HelpAttribute(string url) // url la mot positional parameter
{ this.Url = url; } private string topic; } [HelpAttribute("Thông tin của lớp MyClass")] class MyClass {
} class Tester { static void Main(string[] args) { Console.WriteLine("Reflection trong C#"); Console.WriteLine("--------------------------"); System.Reflection.MemberInfo info = typeof(MyClass); object[] attributes = info.GetCustomAttributes(true); for (int i = 0; i < attributes.Length; i++) { System.Console.WriteLine(attributes[i]); } Console.ReadKey(); } } }

Biên dịch và chạy chương trình C# trên bạn sẽ nhận được kết quả:

Reflection trong C#
--------------------------
VdMetadata.HelpAttribute

Ví dụ

Trong ví dụ này, chúng ta sử dụng attribute là DeBugInfo được tạo trong bài trước và sử dụng Reflection để đọc metadata trong Rectangle class.

using System; using System.Reflection; namespace QTMCSharp { // 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 { 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; } } }
 [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()); }  } //Hết lớp Rectangle
class ExecuteRectangle { static void Main(string[] args) { Rectangle r = new Rectangle(4.5, 7.5); r.Display(); Type type = typeof(Rectangle); //lặp qua các thuộc tính của lớp Rectangle. foreach (Object attributes in type.GetCustomAttributes(false)) { DeBugInfo dbi = (DeBugInfo)attributes; if (null != dbi) { Console.WriteLine("Mã lỗi: {0}", dbi.BugNo); Console.WriteLine("Nhà phát triển: {0}", dbi.Developer); Console.WriteLine("Xem lần cuối: {0}", dbi.LastReview); Console.WriteLine("Ghi chú: {0}", dbi.Message); } } // lặp qua các thuộc tính của phương thức. foreach (MethodInfo m in type.GetMethods()) { foreach (Attribute a in m.GetCustomAttributes(true)) { DeBugInfo dbi = (DeBugInfo)a; if (null != dbi) { Console.WriteLine("Bug no: {0}, for Method: {1}", dbi.BugNo, m.Name); Console.WriteLine("Developer: {0}", dbi.Developer); Console.WriteLine("Last Reviewed: {0}", dbi.LastReview); Console.WriteLine("Remarks: {0}", dbi.Message); } } } Console.ReadLine(); } } }

 

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

Chiều dài: 4.5
Chiều rộng: 7.5
Diện tích: 33.75
Mã lỗi: 45
Nhà phát triển: Nguyễn Huy
Xem lần cuối: 03/09/2017
Ghi chú: Kiểu trả về không hợp lệ
Mã lỗi: 49
Nhà phát triển: Hà Minh
Xem lần cuối: 09/11/2017
Ghi chú: Biến chưa được sử dụng
Bug no: 55, for Method: tinhS
Developer: Nguyễn Huy
Last Reviewed: 03/09/2017
Remarks: Kiểu trả về không hợp lệ
Bug no: 56, for Method: Display
Developer: Hà Minh
Last Reviewed: 09/11/2017
Remarks:

Theo Tutorialspoint

Bài trước: Attribute trong C#

Bài tiếp: Indexer trong C#

Thứ Hai, 30/07/2018 15:02
51 👨 199