Reflection ใน .NET ใช้ Namespace System.Reflection เพื่อตรวจสอบและจัดการ Type, Assembly, Module, Member ใน Runtime
หลักการใช้งานหลัก
- Inspect Type Metadata (Properties, Methods, Fields, Attributes)
- Dynamic Object Creation (Activator.CreateInstance)
- Dynamic Method Invocation (MethodInfo.Invoke)
- Late Binding (Plugin Systems, Serialization, ORM, DI Containers)
- Runtime Code Generation (Expression Trees, IL Emit)
ตัวอย่าง: อ่าน Custom Attributes
using System;
using System.Reflection;
// Custom Attribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class HelpAttribute : Attribute
{
public string Url { get; }
public string Topic { get; set; }
public HelpAttribute(string url) => Url = url;
}
// ใช้ Attribute
[HelpAttribute("https://example.com/docs", Topic = "Getting Started")]
public class MyClass
{
[HelpAttribute("https://example.com/api/do-work", Topic = "API")]
public void DoWork() { }
}
// Reflection: อ่าน Attributes
public class Program
{
public static void Main()
{
// 1. Get Type Info
Type type = typeof(MyClass);
// 2. Class-Level Attributes
Console.WriteLine("Class Attributes:");
foreach (Attribute attr in type.GetCustomAttributes(true))
{
if (attr is HelpAttribute help)
Console.WriteLine($" URL: {help.Url}, Topic: {help.Topic}");
}
// 3. Method-Level Attributes
Console.WriteLine("\nMethod Attributes:");
foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
var attrs = method.GetCustomAttributes(true);
foreach (var help in attrs)
Console.WriteLine($" {method.Name}: {help.Url} - {help.Topic}");
}
// 4. Create Instance Dynamically
object instance = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("DoWork");
method.Invoke(instance, null);
}
}
ผลลัพธ์
Class Attributes:
URL: https://example.com/docs, Topic: Getting Started
Method Attributes:
DoWork: https://example.com/api/do-work - API
Common Reflection Operations
| Task | API |
| Get Type from String | Type.GetType("Namespace.ClassName") |
| Get Type from Instance | obj.GetType() |
| Create Instance | Activator.CreateInstance(type, args) |
| Get Properties | type.GetProperties(bindingFlags) |
| Get/Set Property Value | prop.GetValue(obj) / prop.SetValue(obj, value) |
| Get Methods | type.GetMethods(bindingFlags) |
| Invoke Method | method.Invoke(obj, parameters) |
| Get Fields | type.GetFields(bindingFlags) |
| Get/Set Field Value | field.GetValue(obj) / field.SetValue(obj, value) |
| Get Constructors | type.GetConstructors(bindingFlags) |
| Get Custom Attributes | type.GetCustomAttributes<T>(inherit) |
BindingFlags (ควบคุม Visibility)
var flags = BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Instance | BindingFlags.Static
| BindingFlags.DeclaredOnly; // ไม่รวม Inherited
Performance Considerations
- Reflection ช้ากว่า Direct Call ~10-100x
- Cache `MethodInfo`, `PropertyInfo`, `Type` Objects
- ใช้ `Delegate.CreateDelegate` สำหรับ Repeated Calls
- Expression Trees / Source Generators สำหรับ High-Perf Scenarios
Delegate Cache Pattern
public static class ReflectionCache
{
private static readonly Dictionary> _setters = new();
private static readonly Dictionary> _getters = new();
public static void SetProperty(T obj, string propName, object value)
{
if (!_setters.TryGetValue(propName, out var setter))
{
var prop = typeof(T).GetProperty(propName);
setter = (o, v) => prop.SetValue(o, v);
_setters[propName] = setter;
}
setter(obj, value);
}
}
Security & Safety
- Reflection สามารถเข้าถึง Private Members ได้ (ถ้า Full Trust)
- Sandbox/Partial Trust: Restricted
- Trimmed Apps (AOT): Reflection อาจล้มเหลว - ต้อง Preserve Types
Modern Alternatives
| Use Case | Modern Alternative |
| DI Container | Microsoft.Extensions.DependencyInjection |
| JSON Serialization | System.Text.Json (Source Gen) |
| ORM Mapping | EF Core / Dapper |
| Property Copy/Map | AutoMapper / Mapster |
| Plugin System | AssemblyLoadContext + Interfaces |