2

我正在尝试使用Reflection(假设对象初始化不依赖于要调用的函数)来调用类的函数,如下所示

/// <summary>
    /// Calls a static public method. 
    /// Assumes that the method returns a string
    /// </summary>
    /// <param name="assemblyName">name of the assembly containing the class in which the method lives.</param>
    /// <param name="namespaceName">namespace of the class.</param>
    /// <param name="typeName">name of the class in which the method lives.</param>
    /// <param name="methodName">name of the method itself.</param>
    /// <param name="stringParam">parameter passed to the method.</param>
    /// <returns>the string returned by the called method.</returns>
    /// 
    public static string InvokeStringMethod5(string assemblyName, string namespaceName, string typeName, string methodName, string stringParam)
    {
        //This method was created incase Method has params with default values. If has params will return error and not find function
        //This method will choice and is the preffered method for invoking 

        // Get the Type for the class
        Type calledType = Type.GetType(String.Format("{0}.{1},{2}", namespaceName, typeName, assemblyName));
        String s = null;

        // Invoke the method itself. The string returned by the method winds up in s.
        // Note that stringParam is passed via the last parameter of InvokeMember, as an array of Objects.

        if (MethodHasParams(assemblyName, namespaceName, typeName, methodName))
        {
            s = (String)calledType.InvokeMember(
                        methodName,
                        BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
                        null,
                        null,
                        new Object[] { stringParam });
        }
        else
        {
            s = (String)calledType.InvokeMember(
            methodName,
            BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
            null,
            null,
            null);
        }

        // Return the string that was returned by the called method.
        return s;

    }

    public static bool MethodHasParams(string assemblyName, string namespaceName, string typeName, string methodName)
    {
        bool HasParams;
        string name = String.Format("{0}.{1},{2}", namespaceName, typeName, assemblyName);
        Type calledType = Type.GetType(name);
        MethodInfo methodInfo = calledType.GetMethod(methodName);
        ParameterInfo[] parameters = methodInfo.GetParameters();

        if (parameters.Length > 0)
        {
            HasParams = true;
        }
        else
        {
            HasParams = false;
        }

        return HasParams;

    }  

这是在这里形成的。

有没有其他/更好的方法来做到这一点?

这个活动可以通用吗?就像在.Net 4.0中使用Dynamicand一样可以调用Non-Static methods,这样返回类型就可以独立了。

我从未dynamic在实际场景中使用过关键字(仅阅读一些示例)来实际使用我仍然不知道

在这方面的任何帮助/方向将不胜感激谢谢

4

2 回答 2

2

回答您的查询dynamic;不,这不适合这里。dynamic当成员名称(或操作)在编译时已知但无法证明存在时很有用 - 基本上是鸭子类型。例如:

dynamic foo = GetSomeRandomObject();
foo.ThisShouldExist("abc");

这做类似的事情,但用法不同。所以,是的,你留下了反思。你在做什么是非常正确的。我唯一可能改变的是获取MethodInfo, 并从那里工作 - 虽然如果你可以改变 API 来接受一个单一的string assemblyQualifiedName它会更方便和灵活。但也许:

public static string InvokeStringMethod5(string assemblyName,
    string namespaceName, string typeName, string methodName, string stringParam)
{
    string assemblyQualifiedName = string.Format("{0}.{1},{2}",
        namespaceName, typeName, assemblyName);
    Type calledType = Type.GetType(assemblyQualifiedName);
    if(calledType == null) throw new InvalidOperationException(
        assemblyQualifiedName + " not found");
    MethodInfo method = calledType.GetMethod(methodName,
        BindingFlags.Public | BindingFlags.Static);
    switch (method.GetParameters().Length)
    {
        case 0:
            return (string)method.Invoke(null, null);
        case 1:
            return (string)method.Invoke(null, new object[] { stringParam });
        default:
            throw new NotSupportedException(methodName
                + " must have 0 or 1 parameter only");
    }
}
于 2012-10-11T09:52:40.417 回答
1

要回答有关如何将结果转换为通用返回类型的问题,该方法类似于:

public static T InvokeMethod<T>(string assemblyName, string namespaceName, string typeName, string methodName, string stringParam)
{
    // instead of String s = null;
    T methodResult = default(T);

    // instead of s = (String)calledType.InvokeMember(...)
    methodResult = (T)calledType.InvokeMember(...);

    // return s;
    return methodResult;
}
于 2012-10-11T11:57:22.463 回答