2013-04-10 59 views
4

我有一个静态的方法的泛型类给出使用类型参数的方法:访问静态方法,其中T是由一个类型实例

GenericClass<T> 
{ 
    public static void Method() 
    { 
     //takes info from typeof(T) 
    } 
} 

现在,我需要访问的静态方法,但不能简单地使用GenericClass<KnownType>.Method()。我需要做一个Type实例。所以:

public void OutsiderMethod(Type T) 
{ 
    GenericClass<T>.Method() 
    //it's clear this line won't compile, for T is a Type instance 
    //but i want some way to have access to that static method. 
} 

使用反射,我大概可以得到一个方式,通过它的字符串名称来调用该方法,使用一些MethodInfo的东西。 这部分好,解决了这个问题。 但是,如果可能的话,我很乐意不用这个名字作为字符串。

任何???

+1

扩展方法不适合这种情况吗? – 2013-04-10 16:50:28

+0

这将需要一个GenericClass 的实例,其中T由Type实例给出。 – 2013-04-10 16:59:51

回答

5

非泛型类的泛型方法比泛型类的非泛型方法更容易访问。

您可以创建简单地调用真正的方法,一个辅助方法:

void OutsiderMethodHelper<T>() 
{ 
    GenericClass<T>.Method(); 
} 

然后,您可以得到MethodInfo该方法,无需通过名称作为字符串寻找它:

public void OutsiderMethod(Type T) 
{ 
    Action action = OutsiderMethodHelper<object>; 
    action.Method.GetGenericMethodDefinition().MakeGenericMethod(T).Invoke(null, null); 
} 
+0

嗯,听起来不错!我会测试它。同时,新手问题:是否真的需要创建委托?为什么'MakeGenericMethod'出现在'Method'中时'GetGenericMethodDefinition'? – 2013-04-10 17:21:11

+0

有没有反思文学我可以找到更好地学习它? – 2013-04-10 17:23:27

+0

@Daniel C#允许你在不调用函数的情况下引用一个函数,并没有那么多的情况,创建一个委托就是这样一种情况,并且可能是最简单的。代理用于'OutsiderMethodHelper ','GetGenericMethodDefinition()'为'OutsiderMethodHelper <>'提供'MethodInfo','MakeGenericMethod'允许你填写类型参数。如果您跳过'GetGenericMethodDefinition()',则会得到一个异常,因为'OutsiderMethodHelper '没有任何需要填充的泛型类型参数。 – hvd 2013-04-10 17:26:11

0

这是使用的示例

public static class GenericHelper 
{ 
    public static object Invoke(Expression<Action> invokeMethod, object target, Type genericType, params object[] parameters) 
    { 
     MethodInfo methodInfo = ParseMethodExpression(invokeMethod); 
     if (!methodInfo.DeclaringType.IsGenericType) 
      throw new ArgumentException("The method supports only generic types"); 
     Type type = methodInfo.DeclaringType.GetGenericTypeDefinition().MakeGenericType(genericType); 
     MethodInfo method = type.GetMethod(methodInfo.Name); 
     return method.Invoke(target, parameters); 
    } 

    public static object Invoke(Expression<Action> invokeMethod, Type genericType, params object[] parameters) 
    { 
     return Invoke(invokeMethod, null, genericType, parameters: parameters); 
    } 

    private static MethodInfo ParseMethodExpression(LambdaExpression expression) 
    { 
     Validate.ArgumentNotNull(expression, "expression"); 
     // Get the last element of the include path 
     var unaryExpression = expression.Body as UnaryExpression; 
     if (unaryExpression != null) 
     { 
      var memberExpression = unaryExpression.Operand as MethodCallExpression; 
      if (memberExpression != null) 
       return memberExpression.Method; 
     } 
     var expressionBody = expression.Body as MethodCallExpression; 
     if (expressionBody != null) 
      return expressionBody.Method; 
     throw new NotSupportedException("Expession not supported"); 
    } 
} 

方法调用将如下所示:

GenericHelper.Invoke(() => GenericClass<object>.Method(), typeof(string)); 
相关问题