Reflection được sử dụng để lấy thông tin kiểu dữ liệu trong thời gian chạy. Các lớp cung cấp quyền truy cập vào siêu dữ liệu của một chương trình đang chạy nằm trong namespace System.Reflection .
Namespace System.Reflection chứa các lớp cho phép bạn lấy thông tin về ứng dụng và tự động thêm các kiểu, giá trị và đối tượng vào ứng dụng.
Reflection có các ứng dụng sau:
Chúng tôi đã đề cập trong hướng dẫn trước rằng bạn có thể đọc thông tin thuộc tính bằng cách sử dụng Reflection. Nếu bạn bỏ lỡ bài viết này thì có thể xem tại đây:
Các đối tượng MemberInfo của lớp System.Reflection cần được khởi tạo để khám phá các thuộc tính liên kết với một lớp. Để làm điều này, bạn khai báo như sau:
System.Reflection.MemberInfo info = typeof(MyClass);
Chương trình sau đây minh họa điều này:
using System;
[AttributeUsage(AttributeTargets.All)]
public class HelpAttribute : System.Attribute
{
private string _topic;
public readonly string Url;
public string Topic // Topic is a named parameter
{
get { return _topic; }
set { _topic = value; }
}
public HelpAttribute(string url) // url is a positional parameter
{
this.Url = url;
}
}
[HelpAttribute("Information on the class MyClass")]
class MyClass
{
}
namespace AttributeAppl
{
class Program
{
static void Main(string[] args)
{
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();
}
}
}
Khi được biên dịch và chạy, nó sẽ hiển thị tên của các attribute tùy chỉnh được sử dụng trong lớp MyClass:
HelpAttribute
Trong ví dụ này, chúng tôi sử dụng attribute DebugInfoAttribute được tạo trong chương trước và sử dụng Reflection để đọc siêu dữ liệu trong lớp Rectangle.
using System;
using System.Reflection;
namespace BugFixApplication
{
//a custom attribute BugFix to be assigned to a class and its members
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DebugInfoAttribute : System.Attribute
{
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DebugInfoAttribute(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, "Zara Ali", "12/8/2019", Message = "Return type mismatch")]
[DebugInfo(49, "Nuha Ali", "10/10/2019", Message = "Unused variable")]
class Rectangle
{
//member variables
protected double length;
protected double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
[DebugInfo(55, "Zara Ali", "19/10/2019", Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DebugInfo(56, "Zara Ali", "19/10/2019")]
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}//end class Rectangle
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(4.5, 7.5);
r.Display();
Type type = typeof(Rectangle);
//iterating through the attribtues of the Rectangle class
foreach (Object attr in type.GetCustomAttributes(false))
{
DebugInfoAttribute dbi = attr as DebugInfoAttribute;
if (dbi != null)
{
Console.WriteLine("Bug no: {0}", dbi.BugNo);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last Reviewed: {0}", dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
//iterating through the method attribtues
foreach (MethodInfo m in type.GetMethods())
{
foreach (Attribute a in m.GetCustomAttributes(true))
{
DebugInfoAttribute dbi = a as DebugInfoAttribute;
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();
}
}
}
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
Length: 4.5
Width: 7.5
Area: 33.75
Bug No: 49
Developer: Nuha Ali
Last Reviewed: 10/10/2019
Remarks: Unused variable
Bug No: 45
Developer: Zara Ali
Last Reviewed: 12/8/2019
Remarks: Return type mismatch
Bug No: 55, for Method: GetArea
Developer: Zara Ali
Last Reviewed: 19/10/2019
Remarks: Return type mismatch
Bug No: 56, for Method: Display
Developer: Zara Ali
Last Reviewed: 19/10/2019
Remarks:
Lớp chính để Reflection làm việc là lớp System.Type. Đây là lớp trừu tượng đại diện cho một kiểu dữ liệu trong Hệ thống kiểu chung (CTS). Khi bạn sử dụng lớp này, bạn có thể tìm thấy các kiểu dữ liệu được sử dụng trong một mô-đun và namespace.
Nó cũng xác định xem một kiểu dữ liệu cụ thể là kiểu tham chiếu hay kiểu giá trị. Bạn có thể phân tích các siêu dữ liệu tương ứng để xem qua các thành phần này:
Các ràng buộc muộn (late bindings) cũng có thể thực hiện được bằng cách sử dụng Reflection.
Hãy xem ví dụ sau, bạn có nhiều assembly để thực hiện một số tác vụ khác nhau và không biết chính xác assembly nào sẽ được nạp trong thời gian biên dịch. Trong trường hợp này, bạn có thể yêu cầu người dùng chọn assembly trong thời gian chạy để ứng dụng có thể nạp assembly đó.
Bạn có thể làm điều đó bằng cách sử dụng một trong các phương thức sau của lớp System.Reflection.Assembly:
Có một số lớp tiện ích của Reflection trong C# như sau:
Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
Trong loạt bài này, tôi sẽ xem xét một số
Ngôn ngữ C# đã bật các bộ tăng áp liên
Trong bài viết này, chúng ta sẽ tìm hiểu lớp tiện ích ZipFile trong C#, cách nén tập tin và thư mục, cùng với giải nén tập tin zip.
Bài viết này sẽ giới thiệu cách đơn giản nhất mà tôi đã tìm thấy để đọc và ghi file Excel bằng C# sử dụng ExcelMapper.