我有以下方法:
public MethodInfo FancyGetMethodInfo
(object obj, string methodName, Type[] methodSignature)
{
return obj.GetType().GetMethod(methodName, methodSignature);
}
对于我的对象中的一个例子,我传递了两个方法
public int Subtract(int a, int b) { return a - b; }
public int Add(params int[] a) { return a.Sum(); }
当我执行以下行时,我得到了这些结果:
var SubMethod = FancyGetMethodInfo(obj, "Subtract",
new Type[] { typeof(int), typeof(int) });
//I get a MethodInfo
var AddMethod = FancyGetMethodInfo(obj, "Add",
new Type[] { typeof(int), typeof(int) });
//I get a Null reference
我敢肯定这是因为Add中的参数。是否有一种干净的方法来引用我的MethodInfo为我的Add方法给定一个任意大小的类型[]包含int,只能访问我的FancyGetMethodInfo方法中提供的变量?
编辑:Jon Skeet更雄辩地说,我想在我的方法中执行与c#编译器相同的绑定。它需要与子类,隐式转换,任意长度参数等正常工作…
同样按照要求,这里有一个相关的链接:确定参数是否使用"params"在c#中使用反射?这会让我知道这个方法有一个参数。
你可以:
- 查找所有名称正确的方法
- 对于每种方法:
- 检查方法中的最后一个参数是否是一个"params"数组(根据这个问题;感谢yas4891)
- 检查到但不包括最后一个参数的参数类型是否与方法 上的参数类型匹配
- 检查剩余参数类型是否都与最终参数 的数组元素类型匹配
注意,一旦你找到了一个匹配(而不是找到了一个不需要展开这个参数的匹配),你就需要记住,这样你就可以在以后适当地处理参数(假设你想实际调用这个方法)。
老实说,这有点麻烦……在我看来,你有三个选择:
- 更改调用者以传递
typeof(int[])
,您现有的代码将工作 - 更改
FancyGetMethodInfo
以处理上述参数数组 - 更改
Sum
以接受两个整数(或可能有各种过载)
这不是因为参数(尽管这可能会带来额外的问题)。
试试相反:var AddMethod = FancyGetMethodInfo(obj,"添加",new Type[] {typeof(int[])});
params参数只是普通数组的语法糖。
int Add(params int[] a)
相当于CLR透视图中的
int Add(int[] a)
参数修饰符只是c#的语法糖。
这意味着如果你想使用反射找到你的方法,你将需要以下调用:
var AddMethod = FancyGetMethodInfo(obj, "Add",
new Type[] { typeof(int[]) });
如果你想进一步测试方法是否包含params参数,你需要测试它是否将ParamArrayAttribute应用于方法的最后一个参数
你试过这个吗?
来自MSDN: Type。GetMethod
public void MethodA(int[] i) { }
// Get MethodA(int[] i)
mInfo = typeof(Program).GetMethod("MethodA",
BindingFlags.Public | BindingFlags.Instance,
null,
new Type[] { typeof(int[]) },
null);
Console.WriteLine("Found method: {0}", mInfo);
如何检查"params"关键字:这里已经回答了