Po googlowania i lądowania na SO i po przeczytaniu this other questionBuduje delegata z MethodInfo?
Czy możliwe jest zbudowanie prawidłowego Delegata z MethodInfo jeśli nie wiesz ilości i typów parametrów w czasie kompilacji?
Więcej na ten temat: czy można to zrobić elegancko, bez użycia Reflection.Emit lub typu budowniczych?
Jest to dla mnie trochę kłopotliwe, ponieważ Delegate.CreateDelegate wymaga od mnie określenia właściwego typu Delegata jako pierwszego parametru, inaczej wyrzuciłby wyjątki lub wywołałby niepoprawną metodę.
Buduję trochę narzędzi ninja, a to by bardzo pomogło ... Dzięki!
Oto generic rozwiązanie:
/// <summary>
/// Builds a Delegate instance from the supplied MethodInfo object and a target to invoke against.
/// </summary>
public static Delegate ToDelegate(MethodInfo mi, object target)
{
if (mi == null) throw new ArgumentNullException("mi");
Type delegateType;
var typeArgs = mi.GetParameters()
.Select(p => p.ParameterType)
.ToList();
// builds a delegate type
if (mi.ReturnType == typeof(void)) {
delegateType = Expression.GetActionType(typeArgs.ToArray());
} else {
typeArgs.Add(mi.ReturnType);
delegateType = Expression.GetFuncType(typeArgs.ToArray());
}
// creates a binded delegate if target is supplied
var result = (target == null)
? Delegate.CreateDelegate(delegateType, mi)
: Delegate.CreateDelegate(delegateType, target, mi);
return result;
}
Uwaga: Buduję aplikacji Silverlight, która zastąpi wbudowaną lat-temu javascript aplikację, w której mam wiele Interfejsy JavaScript wywołujące tę samą metodę Silverlight [ScriptableMember].
Wszystkie starsze interfejsy JS muszą być obsługiwane, a także nowy interfejs dostępu do nowych funkcji, więc coś, co automatycznie konfiguruje interfejs JS i "deleguje" połączenie do odpowiedniej metody Silverlight, znacznie przyspieszy pracę.
Nie mogę opublikować kodu tutaj, więc to jest podsumowanie.
Buduję to, aby skleić razem Silverlight [ScriptableMember] i osobny interfejs JavaScript, więc nie muszę się martwić o synchronizowanie sygnatur metod w obu lokalizacjach. – chakrit
Wow .... to bardzo pomogło! Jesteście rocka! – chakrit
@ Marc Gravell, nie jestem w stanie wywołać delegata utworzonego w powyższym kodzie jak d(). Po uruchomieniu go, stwierdziłem, że można użyć metody dynamicInvoke do wywołania metody, która jest bardzo powolna. pls pomoc. Jestem nowy dla delegatów i wydarzeń. moim wymaganiem jest wywołanie metody dynamicznie, liczba lub typ parametrów będzie znana w środowisku wykonawczym tylko – Saranya