Calling a function using reflection that has a “params” parameter (MethodBase)

前端 未结 3 1496
Happy的楠姐
Happy的楠姐 2020-12-11 15:40

I have MethodBases for two functions:

public static int Add(params int[] parameters) { /* ... */ }
public static int Add(int a, int b) { /* ... */ }
<         


        
3条回答
  •  北荒
    北荒 (楼主)
    2020-12-11 16:00

    Supposing we have the following example class:

    public class Test
    {
        public static int Add(int i1, int i2)
        {
            return i1 + i2;
        }
    
        public static int Add(params int[] ints)
        {
            int sum = 0;
            foreach (int i in ints)
                sum += i;
    
            return sum;
        }
    }
    

    To get the MethodInfo objects for each overload of the static Add method you should do the following:

     MethodInfo Add2Ints = typeof(Test).GetMethod("Add",  new Type[] { typeof(int), typeof(int) });
     MethodInfo AddParamsInts = typeof(Test).GetMethod("Add", new Type[] { typeof(int[]) });
    

    In order to invoke any of the two methods, symply pass the arguments with the exact type expected by the specific overload you are invoking:

     Add2Ints.Invoke(null, new object[] { 1, 2 });
     AddParamsInts.Invoke(null, new object[] { new int[] { 1, 2 } });
    

    Note that the following will not work:

     AddParamsInts.Invoke(null, new object[] { 1, 2 }); 
    

    because the signature of AddParmsInt is really (int[]) and although the compiler, as a courtesy, allows you to call such method as (int, int) under the hood what is really happening is that the call is converted for you at the call site to the equivalent (int[]) call. Via reflection you don't have the compiler's "help" so you need to pass the exact argument type defined by the method's signature.

    With all that said, your call method should be as follows:

     public object call(params object[] input)
     {
         return AddParamsInts.Invoke(null /*static*/, new object[] { input.Cast().ToArray() });
     }
    

    Note that you can not directly cast a object[] array to a int[] array: int[] ints = (int[])input. Casting reference typed arrays to value-type arrays is not allowed.

    Also important to note is that the defined overloads of the Add method are useless, as they overlap. Consider only using the params overload or, in case you want to guarantee that at least two arguments are needed in order to evaluate an addition, overload them the following way:

     public int Add(int i1, int i2) { }
     public int Add(int i1, int i2, params int[] args) { }
    

提交回复
热议问题