Я создаю Delegate
из метода, который, как я знаю, принимает только один параметр, а затем вызываю его, используя DynamicInvoke
, но мне было интересно, можно ли было заставить Action
вызывать напрямую.
Вот что у меня сейчас:
private IEnumerable<MethodInfo> GetMethods()
=> GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
private IEnumerable<Thing> GetThings() {
foreach (var method in GetMethods()) {
var attribute = (MyAttribute) method.GetCustomAttribute(typeof(MyAttribute), false);
var theDelegate = CreateDelegate(method);
return new Thing(attribute.Name, theDelegate);
}
}
private Delegate CreateDelegate(MethodInfo method) {
Type requestType = method.GetParameters()[0].ParameterType,
actionType = typeof(Action<>).MakeGenericType(requestType);
return Delegate.CreateDelegate(actionType, this, method);
}
public void Invoke(Thing thing, string json) {
var requestType = MyDelegate.Method.GetParameters()[0].ParameterType;
var o = Deserialize(json, requestType);
thing.TheDelegate.DynamicInvoke(o);
}
Используя Действие, не только будет быстрее, но и намного лучше . Следующий код не работает , но должен быть способ получить что-то похожее:
private Action CreateAction(MethodInfo method) {
Type requestType = method.GetParameters()[0].ParameterType,
actionType = typeof(Action<>).MakeGenericType(requestType);
return (Action) Delegate.CreateDelegate(actionType, this, method);
}
public void Invoke(Thing thing, string json) {
Type requestType = MyAction.GetParameters()[0].ParameterType;
var o = Deserialize(json, requestType);
thing.MyAction(o);
}