如何在涉及参数时测试是否存在有效的方法

时间:2011-08-18 06:34:21

标签: c# .net reflection

我有以下方法:

    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中的参数。给定一个包含int的任意大小的Type [],并且只能访问我的FancyGetMethodInfo方法中提供的变量,是否有一种干净的方法可以为我的Add方法引用我的MethodInfo?

编辑: Jon Skeet更加雄辩地说,我想在我的方法中执行与C#编译器相同的绑定。它需要与子类,隐式转换,任意长度参数等正常工作......

同样根据要求,这里的相关链接是:Determining if a parameter uses "params" using reflection in C#?,这将使我知道该方法有一个参数。

4 个答案:

答案 0 :(得分:1)

嗯,你可以:

  • 找到所有正确名称的方法
  • 对于每种方法:
    • 检查方法中的最后一个参数是否为“params”数组(根据this question;感谢yas4891)
    • 检查您最近参考的参数类型但不包括最后一个参数是否与方法
    • 相匹配
    • 检查剩余的参数类型是否都与最终参数的数组元素类型匹配

请注意,一旦找到匹配项(并且找到了不需要此参数扩展的匹配项),您就需要记住您可以稍后适当地处理参数(假设您想要实际调用该方法)。

说实话,说实话......我认为你有三种选择:

  • 更改呼叫者以传递typeof(int[]),您的现有代码将正常工作
  • 如上所述更改FancyGetMethodInfo以处理参数数组
  • Sum更改为接受两个整数(或可能有各种重载)

取决于您选择哪条路线......

答案 1 :(得分:0)

你试试这个:

来自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”关键字:已回答here

答案 2 :(得分:0)

这不是因为params(虽然这可能会带来额外的问题)。

尝试改为: var AddMethod = FancyGetMethodInfo(obj,“Add”,                          new Type [] {typeof(int [])});

答案 3 :(得分:0)

params 参数只不过是普通数组的语法糖。

    int Add(params int[] a)

等同于从CLR角度来看

    int Add(int[] a)
params 修饰符只是C#语法糖。

这意味着如果您想使用反射找到方法,则需要进行以下调用:

var AddMethod = FancyGetMethodInfo(obj, "Add", 
                         new Type[] { typeof(int[]) }); 

如果你想进一步测试方法是否包含params参数,你需要测试它是否有ParamArrayAttribute应用于方法的最后一个参数。