如何获得嵌套泛型类型的类型

时间:2013-10-19 08:20:06

标签: c# generics types

有这样的第三方组件库:

 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);
    }
}

我想反思调用方法Excute<T>(this GenericExcuteTestClass clazz, string parameter, Action<ReturnClass<T>> callback)

  1. 我使用typeof(GenericExcuteTestClassExtension).GetMethod("Excute", new Type[] { typeof(GenericExcuteTestClass), typeof(string), typeof(Action<ReturnClass<>>)}),但编译器会收到错误“Type expected”。我怎样才能获得(Action<ReturnClass<>>)的类型,Action<>可以卷入其中,但这不是我的预期。

  2. 我想将action<ReturnClass<>>这样的自定义(result)=>{....}传递给该方法,我该怎么做?

  3. 请帮助,谢谢。

    为什么我使用reflect执行此操作?

    因为此方法必须在aop拦截中执行

    这种真实情况是这样的:

    我想在我的应用程序中使用restsharp,并编写一个类似

    的界面
     [RestfulService(Constants.BASE_URL + "/login")]
     public interface UserService
     {
        [Request("/login")]
        void Login([Paramter] string name, [Paramter] string password, Action<T> callBack);
     }
    

    并拦截接口以获取参数以执行restsharp ExecuteAsync<T>(this IRestClient client, IRestRequest request, Action<IRestResponse<T>> callback)以获取数据。

    所以我需要在Intercept方法T中将UserService中的ExecuteAsync<T>传递给public void Intercept(IInvocation invocation) of castle.windsor,在这个方法体中,我们只能得到GenericType的Type cannnot get T,所以如果我直接调用ExecuteAsync,我无法将GenericType T传递给此方法。我必须这样使用:...GetMethod("...").MakeGenericType(new Type[]{piLast.ParameterType.GenericTypeArguments})

1 个答案:

答案 0 :(得分:1)

整个问题来自这样一个事实,即.NET中的反射系统无法很好地处理嵌套泛型类型。

您的案例中最简单的解决方案是自己过滤方法。一个快速和肮脏的片段:

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;
    }
}

你应该从中做出一个实用方法。可以找到允许搜索具有嵌套泛型的任何方法的一般方法here。使用Expressions here还有另一种可能性。