使用类名和方法名调用类的成员 [英] Invoking Member of a class using Class Name and Method Name

查看:98
本文介绍了使用类名和方法名调用类的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Reflection 调用类的函数(假设对象初始化为不依赖于要调用的函数),就像这样

  ///< summary> 
///调用静态公共方法。
///假定该方法返回字符串
///< / summary>
///< param name = assemblyName>包含该方法所在类的程序集的名称。
///< param name = namespaceName>该类的命名空间。< / param>
///< param name = typeName>该方法所在的类的名称。< / param>
///< param name = methodName>方法本身的名称。< / param>
///< param name = stringParam>参数传递给该方法。< / param>
///< returns>由被调用方法返回的字符串。
///
公共静态字符串InvokeStringMethod5(字符串assemblyName,字符串namespaceName,字符串typeName,字符串methodName,字符串stringParam)
{
//此方法是在方法具有参数的情况下创建的使用默认值。如果有参数将返回错误,并且找不到函数
//此方法将选择并且是调用

的首选方法//获取类
的Type类型TypeType = Type.GetType(String.Format( {0}。{1},{2},namespaceName,typeName,assemblyName));
String s = null;

//调用方法本身。方法返回的字符串以s结尾。
//注意,stringParam作为对象数组通过InvokeMember的最后一个参数传递。

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

//返回被调用方法返回的字符串。
return s;

}

public static bool MethodHasParams(string assemblyName,string namespaceName,string typeName,string methodName)
{
bool HasParams;
字符串名称= String.Format( {0}。{1},{2},namespaceName,typeName,assemblyName);
类型为Type = Type.GetType(name);
MethodInfo methodInfo = namedType.GetMethod(methodName);
ParameterInfo []参数= methodInfo.GetParameters();

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

返回HasParams;

}

这是从此处



还有其他/更好的方法吗?



此活动可以是一般性的吗?就像使用 Dynamic 并可以在.Net 4.0中调用非静态方法这样返回类型可以是独立的。 / p>

在实际情况中,我从未使用过 dynamic 关键字(仅阅读了一些示例)来使动手用法对我来说仍然是未知的



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

解决方案

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

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

这可以做类似的事情,但是用法不同。所以,是的,您留下了反思。您正在做的事情非常正确。我唯一可能要更改的就是获取 MethodInfo ,然后从那里开始工作-尽管如果您可以更改API以接受单个 string assemblyQualifiedName, 会更加方便和灵活。但是也许:

 公共静态字符串InvokeStringMethod5(字符串assemblyName,
字符串命名空间名称,字符串typeName,字符串methodName,字符串stringParam )
{
string assemblyQualifiedName = string.Format( {0}。{1},{2},
namespaceName,typeName,assemblyName);
类型为Type = Type.GetType(assemblyQualifiedName);
if(namedType == null)抛出新的InvalidOperationException(
assemblyQualifiedName + not found);
MethodInfo方法= namedType.GetMethod(methodName,
BindingFlags.Public | BindingFlags.Static);
开关(method.GetParameters()。Length)
{
case 0:
return(string)method.Invoke(null,null);
情况1:
返回(字符串)方法。Invoke(null,new object [] {stringParam});
默认值:
抛出new NotSupportedException(methodName
+必须仅具有0或1个参数);
}
}


I am trying to invoke function of a class using Reflection (assuming that object initialization as no dependency on Function to be invoked) like this

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

    }  

This was taken form here.

Is there any other/better way to do this ??

Can this activity be generalship. Like using Dynamic and can call Non-Static methods in .Net 4.0 so that the return type can be independent.

I have never used dynamic keyword in actual scenario (only read some examples) to actul usage still unknown to me

Any help/direction in this regard would be appreciated Thanks

解决方案

To answer you query on dynamic; no, that wouldn't be a good fit here. dynamic is useful when the member-name (or operation) is known at compile-time, but is not provable to exist - basically, duck-typing. For example:

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

this does similar things, but the usage is different. So yes, you're left with reflection. What you are doing is pretty-much right. The only thing I might change would be to obtain the MethodInfo, and work from there - although if you can change the API to accept a single string assemblyQualifiedName it would be more convenient and flexible. But perhaps:

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

这篇关于使用类名和方法名调用类的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆