Reflection در C#

Reflection یکی از قابلیت‌های قدرتمند در زبان C# و .NET است که به برنامه‌نویس اجازه می‌دهد در زمان اجرا (Runtime) به ساختار و متادیتای (Metadata) برنامه دسترسی پیدا کند.
با Reflection می‌توانیم اطلاعاتی مثل کلاس‌ها، متدها، پراپرتی‌ها، فیلدها و Attributeها را بررسی کرده یا حتی آن‌ها را به صورت پویا (Dynamic) اجرا کنیم.

به بیان ساده، Reflection یعنی نگاه کردن به داخل اسمبلی (Assembly) در زمان اجرا.


چرا Reflection مهم است؟

تصور کنید می‌خواهید:

  • تمام متدهای یک کلاس را در زمان اجرا پیدا کنید.

  • یک متد خاص را بدون دانستن نامش در زمان کامپایل اجرا کنید.

  • تمام ثابت‌های (const) یک کلاس را به‌صورت داینامیک لیست کنید.

  • ابزاری بسازید که بدون کدنویسی دستی، API یا CRUD تولید کند.

تمام این کارها با Reflection ممکن است.


مثال‌های عملی

۱. گرفتن اطلاعات یک کلاس

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    public void SayHello() => Console.WriteLine($"Hello, I am {Name}");
}

در زمان اجرا می‌توانیم اطلاعات کلاس را بگیریم:

var type = typeof(Person);

Console.WriteLine(type.Name);       // Person
Console.WriteLine(type.Namespace);  // فضای نام

foreach (var prop in type.GetProperties())
{
    Console.WriteLine($"Property: {prop.Name} - {prop.PropertyType}");
}

۲. اجرای متد در زمان اجرا

var person = new Person { Name = "Ali" };
var type = person.GetType();
var method = type.GetMethod("SayHello");
method.Invoke(person, null);

حتی اگر نام متد را از قبل ندانیم، در زمان اجرا می‌توانیم آن را پیدا کرده و اجرا کنیم.


۳. گرفتن تمام ثابت‌ها (Const) با Reflection

public static class Constants
{
    public const string AppName = "Sametrix";
    public const string Version = "1.0";
}

کلاس Helper:

public static class ReflectionHelper
{
    public static IEnumerable<string> GetConstStrings<T>()
    {
        return typeof(T)
            .GetFields(System.Reflection.BindingFlags.Public |
                       System.Reflection.BindingFlags.Static |
                       System.Reflection.BindingFlags.FlattenHierarchy)
            .Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(string))
            .Select(fi => fi.GetRawConstantValue().ToString());
    }
}

و استفاده:

var values = ReflectionHelper.GetConstStrings<Constants>();
// خروجی: [ "Sametrix", "1.0" ]

کاربردهای Reflection

  • ORMها مثل Entity Framework برای نگاشت کلاس‌ها به دیتابیس.

  • Dependency Injection برای کشف و ثبت سرویس‌ها.

  • Serialization / Deserialization مثل JSON.Net.

  • Attribute-based programming (مثل [Authorize], [HttpGet]).

  • ساخت ابزارهای داینامیک (مثل گرفتن لیست ثابت‌ها یا ساخت فرم و API اتوماتیک).


مزایا و معایب

✅ مزایا

  • انعطاف‌پذیری بالا در طراحی سیستم‌های داینامیک.

  • امکان کار با کدی که در زمان کامپایل شناخته‌شده نیست.

  • مناسب برای ساخت ابزارها، فریم‌ورک‌ها و کتابخانه‌ها.

❌ معایب

  • سرعت پایین‌تر نسبت به دسترسی مستقیم.

  • پیچیدگی بیشتر کد و سخت‌تر شدن دیباگ.

  • خطاهای زمان اجرا در صورت استفاده اشتباه.


نکات Best Practice

  1. تا حد ممکن کم استفاده کنید. فقط در جاهایی که واقعاً نیاز است.

  2. برای عملیات پرتکرار، نتایج Reflection را Cache کنید تا سرعت بیشتر شود.

  3. اگر می‌شود با Generic یا Expression حل کرد، از آن‌ها استفاده کنید.


جمع‌بندی

Reflection یک ابزار قدرتمند در C# است که امکان بررسی و تغییر ساختار برنامه در زمان اجرا را فراهم می‌کند. این قابلیت در بسیاری از فریم‌ورک‌ها و ابزارهای بزرگ مثل Entity Framework، ASP.NET Core و Newtonsoft.Json استفاده شده است.

با این حال باید با احتیاط استفاده شود، چون می‌تواند کارایی و خوانایی کد را کاهش دهد.