Reflection คือเมื่อ Managed Code สามารถอ่าน Metadata ของตัวเองเพื่อหา Assemblies โดยพื้นฐานแล้วมันอนุญาตให้โค้ดตรวจสอบโค้ดอื่นภายในระบบเดียวกัน ใน C# Reflection เราสามารถสร้างอินสแตนซ์ของ Type แบบ Dynamic และ Bind Type นั้นกับออบเจกต์ที่มีอยู่แล้ว นอกจากนี้ เรายังสามารถรับ Type จากออบเจกต์ที่มีอยู่และเข้าถึง Properties ของมันได้ เมื่อเราใช้ Attributes ในโค้ด Reflection ให้การเข้าถึงได้ เนื่องจากมันจัดเตรียมออบเจกต์ของ Type ที่อธิบาย Modules, Assemblies และ Types
สมมติว่าเรามี Property ประเภท double และใน Runtime เรามีค่าเป็น String และต้องการ Assign ให้ Property หลังจากเปลี่ยน Type แล้ว เราสามารถใช้ Convert.ChangeType() - มันอนุญาตให้เราใช้ข้อมูล Runtime บน Type ใดๆ ที่ implement IConvertible เพื่อเปลี่ยนรูปแบบการแสดงผล
ตัวอย่าง
using System;
using System.Reflection;
namespace DemoApplication {
class Program {
static void Main() {
Circle circle = new Circle();
string value = "6.5";
PropertyInfo propertyInfo = circle.GetType().GetProperty("Radius");
// แปลง String เป็น Type ของ Property (double) แล้ว Set ค่า
propertyInfo.SetValue(circle, Convert.ChangeType(value, propertyInfo.PropertyType), null);
var radius = circle.GetType().GetProperty("Radius").GetValue(circle, null);
Console.WriteLine($"Radius: {radius}");
Console.ReadLine();
}
}
class Circle {
public double Radius { get; set; }
}
}
Output
Radius: 6.5
ในตัวอย่างข้างต้น เราเห็นว่าค่า String "6.5" ถูกแปลงเป็น Type จริงคือ double โดยใช้ Convert.ChangeType และ Assign ให้ Property Radius ผ่าน Reflection ใน Runtime
กรณีที่ซับซ้อนกว่า: Enum และ Custom Types
public enum Status { Active = 1, Inactive = 2, Pending = 3 }
public class User {
public Status UserStatus { get; set; }
public DateTime CreatedDate { get; set; }
}
class Program {
static void Main() {
User user = new User();
// Set Enum จาก String
string statusStr = "Active";
PropertyInfo statusProp = user.GetType().GetProperty("UserStatus");
object statusValue = Enum.Parse(statusProp.PropertyType, statusStr);
statusProp.SetValue(user, statusValue);
// Set DateTime จาก String
string dateStr = "2024-01-15";
PropertyInfo dateProp = user.GetType().GetProperty("CreatedDate");
object dateValue = Convert.ChangeType(dateStr, dateProp.PropertyType);
dateProp.SetValue(user, dateValue);
Console.WriteLine($"Status: {user.UserStatus}");
Console.WriteLine($"CreatedDate: {user.CreatedDate}");
}
}
ข้อควรระวัง
Convert.ChangeTypeทำงานได้เฉพาะ Type ที่ implementIConvertible(Primitive types, DateTime, Decimal, Enum ฯลฯ)- สำหรับ Custom Class/Struct ต้องใช้
TypeConverterหรือ Custom Parsing Logic - ควร Wrap ใน Try-Catch เพื่อจัดการ Exception เมื่อแปลงไม่สำเร็จ
- Performance: Reflection ช้ากว่าการเข้าถึง Property โดยตรง ควร Cache PropertyInfo ไว้ใช้ซ้ำ