Invoking Methods


Once the methods of a type are known (enumerated), it is possible call them using the facilities of reflection. The method Invoke of MethodInfo is the means by which this is done. One form of Invoke is shown below.

object Invoke(object O, object[] arguments)

O is a reference to the object for which the method is called. For static methods, O must be null. Any arguments that need to be passed are specified in the array arguments. The array arguments must contain the exact number of arguments required by the function and the types of the arguments must match its delcaration. To call a function, Invoke is called on an instance of MethodInfo returned when calling GetMethods(). The following program demonstrates how this is done.

// Runtime6 - Invoking Methods

using System;
using System.Reflection;

class X
{
    public int x;
    public int y;

    public X(int i, int j) { x = i; y = j; }

    public int Sum() { return x + y; }

    public void Set(int i, int j)
    {
        x = i; y = j;
        Console.WriteLine("In Set(int,int), value={0}", this);
    }

    public void Set(double u, double v)
    {
        x = (int)u; y = (int)v;
        Console.WriteLine("In Set(double,double, value={0})", this);
    }

    public override string ToString()
    {
        return "(" + x + "," + y + ")";
    }
}

class Program
{
    static void Main()
    {
        Type t = typeof(X);

        X o = new X(10, 20);

        Console.WriteLine("Invoking methods of {0}", t.Name);

        MethodInfo[] methods = t.GetMethods();

        foreach (MethodInfo mi in methods)
        {
            ParameterInfo[] parameters = mi.GetParameters();

            if (mi.Name.CompareTo("Set") == 0 &&
                parameters[0].ParameterType == typeof(int))
            {
                object[] args = new object[2];
                args[0] = 9;
                args[1] = 18;
                mi.Invoke(o, args);
            }

            else if (mi.Name.CompareTo("Set") == 0 &&
                parameters[0].ParameterType == typeof(double))
            {
                object[] args = new object[2];
                args[0] = 1.5;
                args[1] = 2.5;
                mi.Invoke(o, args);
            }

            else if (mi.Name.CompareTo("Sum") == 0)
            {
                int v = (int)mi.Invoke(o, null);
                Console.WriteLine("Sum for {0} = {1}", o, v);
            }
        }
    }
}

The output of this program is shown below.

Invoking methods of X
Sum for (10,20) = 30
In Set(int,int), value=(9,18)
In Set(double,double, value=(1,2))

Three methods are invoked - two Set methods and one Sum method. The MethodInfo array is enumerated and out of all the methods, these three methods are selected. To select a Set method, more information than just the name is required because Set is overloaded. So to select a Set method, the type of the first parameter is also examined. Argument lists for the two Set methods are constructed and the methods are called through Invoke(). For the method Sum(), no parameters are required; however, the method returns a value which is detected and used.