Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

Reflection ใน C# - รันไทม์ Type Inspection และ Dynamic Invocation

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

TaskAPI
Get Type from StringType.GetType("Namespace.ClassName")
Get Type from Instanceobj.GetType()
Create InstanceActivator.CreateInstance(type, args)
Get Propertiestype.GetProperties(bindingFlags)
Get/Set Property Valueprop.GetValue(obj) / prop.SetValue(obj, value)
Get Methodstype.GetMethods(bindingFlags)
Invoke Methodmethod.Invoke(obj, parameters)
Get Fieldstype.GetFields(bindingFlags)
Get/Set Field Valuefield.GetValue(obj) / field.SetValue(obj, value)
Get Constructorstype.GetConstructors(bindingFlags)
Get Custom Attributestype.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 CaseModern Alternative
DI ContainerMicrosoft.Extensions.DependencyInjection
JSON SerializationSystem.Text.Json (Source Gen)
ORM MappingEF Core / Dapper
Property Copy/MapAutoMapper / Mapster
Plugin SystemAssemblyLoadContext + Interfaces