从GenericClass <t>访问静态方法,其中T由Type实例</t>给出

时间:2013-04-10 16:48:01

标签: c# generics reflection types static

我有一个带有静态方法的泛型类,该方法使用类型参数:

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内容来调用该方法。 这部分是好的,解决了这个问题。 但如果可能的话,我很乐意不要将这个名字用作字符串。

任何???

2 个答案:

答案 0 :(得分:5)

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

您可以创建一个简单调用实际方法的辅助方法:

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

然后,您可以获取该方法的MethodInfo,而无需通过name-as-string查找:

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

答案 1 :(得分:0)

以下是使用 Expression

的示例
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));