Очевидно, що ніхто не може відповісти на питання, не намагаючись це робити, а робити тести на продуктивність, щоб дізнатися, чи досягнуто вашої мети.
Віддзеркалення набагато швидше в сучасних версіях системи, ніж раніше, але це все ще не так швидко, як просто виклик делегата.
Моя пропозиція полягає в тому, щоб почати з запропонованого вами рішення: будувати один раз кеш методу:
class MyClass
{
static Dictionary cache = new ...
public void InvokeByName(string name)
{
MethodInfo methodInfo = GetMethodInfoFromCache(name);
methodInfo.Invoke(this, new object[] {});
}
Коли з'явиться запит на виклик методу, ідентифікованого рядком на конкретному прикладі як приймач, знайдіть інформацію про метод за назвою, а потім зателефонуйте йому до даного приймача. Виміряйте продуктивність і подивіться, чи відповідає вона вашою цілі. Якщо це так, здорово; не витрачайте більше на свій дорогоцінний час, намагаючись зробити щось швидше, це вже досить швидко.
Якщо це не досить швидко, ось що я б робив:
class MyClass
{
static Dictionary> cache = new ...
public void InvokeByName(string name)
{
GetActionFromCache(name).Invoke(this);
}
Тож що робить GetActionFromCache? Якщо в кеш-пам'яті вже є дія, ми закінчили. Якщо цього немає, то отримаєте MethodInfo за допомогою Reflection. Потім скористайтеся бібліотекою дерева виразів, щоб створити Lambda:
var methodInfo = SomehowGetTheMethodInfo(name);
// We're going to build the lambda (MyType p)=>p.()
var p = Expression.Parameter(typeof(MyType), "p"));
var call = Expression.Call(p, methodInfo);
var lambda = Expression.Lambda>(call, p);
var action = lambda.Compile();
І тепер у вас є дія в руці, яку ви можете викликати з екземпляром. Прикріпіть це в кеш-пам'яті.
Це, до речі, на неймовірно спрощеному рівні, як працює "динамічний" в C# 4. Наша проблема надзвичайно ускладнюється тим фактом, що ми повинні мати справу з приймачем і аргументами, що складають будь-який тип. У вас це дуже просто порівняно.