我正在尝试使用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;
}
这是从here开始的。
还有其他/更好的方法吗?
这项活动可以是一般性的。与使用Dynamic
一样,可以在.Net 4.0中调用Non-Static methods
,以便返回类型可以是独立的。
我从未在实际场景中使用过dynamic
关键字(仅读取一些示例)以确定我仍然不知道的使用情况
在这方面的任何帮助/方向将不胜感激 谢谢
答案 0 :(得分: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");
}
}
答案 1 :(得分: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;
}