There is a third-party component library like this:
public static class GenericExcuteTestClassExtension
{
public static void Excute<T>(this GenericExcuteTestClass clazz,
string parameter, Action<ReturnClass<T>> callback)
{
ReturnClass<T> rClazz = new ReturnClass<T>(parameter);
rClazz.Property5 = typeof(T).ToString();
callback.Invoke(rClazz);
}
public static void Excute<T>(this GenericExcuteTestClass clazz,
string parameter, Action<ReturnClass> callback)
{
ReturnClass rClazz = new ReturnClass(parameter);
rClazz.Property5 = typeof(T).ToString();
callback.Invoke(rClazz);
}
}
I want to reflect to invoke the methodExcute<T>(this GenericExcuteTestClass clazz, string parameter, Action<ReturnClass<T>> callback).
I use thetypeof(GenericExcuteTestClassExtension).GetMethod("Excute", new Type[] { typeof(GenericExcuteTestClass), typeof(string), typeof(Action<ReturnClass<>>)}), but the compiler get the error "Type expected". How can I get type of (Action<ReturnClass<>>), Action<> can compliled, but it's not my expected.
I want to pass the a custom action<ReturnClass<>> like (result)=>{....} to the method, how can I do it?
Please help ,thanks.
Why I use reflect to execute this ?
Because this method must execute in aop intercept
this real situation is like this:
I want to use restsharp in my app, and I write an interface like
[RestfulService(Constants.BASE_URL + "/login")]
public interface UserService
{
[Request("/login")]
void Login([Paramter] string name, [Paramter] string password, Action<T> callBack);
}
and Intercept the interface to get the parameter to execute restsharp ExecuteAsync<T>(this IRestClient client, IRestRequest request, Action<IRestResponse<T>> callback) to get data.
So I need to pass the T in UserService to ExecuteAsync<T> in Intercept method public void Intercept(IInvocation invocation) of castle.windsor, in this method body, we only can get GenericType's Type cannnot get T, so if I directly call ExecuteAsync, I cannot pass the GenericType T to this method. I must use like this:...GetMethod("...").MakeGenericType(new Type[]{piLast.ParameterType.GenericTypeArguments})
The whole problem comes from the fact, that nested generic types are not well handled by the reflection system in .NET.
The simplest solution in your case is to filter the methods yourself. A quick&dirty snippet:
MethodInfo method = null;
foreach (var m in typeof(GenericExcuteTestClassExtension)
.GetMethods(BindingFlags.Public | BindingFlags.Static))
{
var parameters = m.GetParameters();
if (!parameters.Any())
continue;
var lastParameterType = parameters.Last().ParameterType;
var genericArgument = lastParameterType
.GetGenericArguments()
.SingleOrDefault();
// you can/should add more checks, using the Name for example
if (genericArgument != null && genericArgument.IsGenericType)
{
method = m;
break;
}
}
You should probably make an utility method from this. A general approach allowing to search for any method with nested generics can be found here. There is also another possibility using Expressions here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With