Alternate way to call method

Viewed 64

I have a generic method that accepts two parameters string and object. It is supposed to invoke a method based on string name. The other parameter is received as object which is basically object parameter of the target method.

I am currently maintaining a dictionary that keeps dictionary against passed string and the actual method. Like

public static Dictionary<string, string> ActionMappings = new Dictionary<string, string>
   {
       { "Get Patients", "Patient.GetPatients" },
       /// other mapping...
    };

I am currently invoking the method based on ActionMappings dictionary. I am using reflection like

string className = methodDetailsValues.Split('.')[0];
string methodName = methodDetailsValues.Split('.')[1];
currMethodClass = Type.GetType("NameSpace" + className);


ConstructorInfo stringConstructor = allConstructorsOfClass.First();
object newStringConstructor =  stringConstructor.Invoke(null);
MethodInfo voidMethodInfo = currMethodClass.GetMethod(methodName);
object jsonString =       voidMethodInfo.Invoke(newStringConstructor, new object[] { });

Can I maintain a list of initialized methods? It is working but it seems to be slow in performance.

1 Answers

If all the methods return string and take no parameters, you can solve this by using a Dictionary<string, Func<string>> like so:

Patient patient = new Patient();
// Also instantiate or obtain other classes needed for the dictionary.

Dictionary<string, Func<string>> actionMappings = new ()
{
    ["Get Patients"] = () => patient.GetPatients()
    // Etc
};

Then you could use the dictionary like so:

string jsonString = actionMappings["Get Patients"]();

If for some reason you must create (or somehow obtain) the objects used to return the values at call-time, you can do something like this:

Dictionary<string, Func<string>> actionMappings = new ()
{
    ["Get Patients"] = () =>
    {
        var patient = new Patient();
        return patient.GetPatients();
    }

    // Etc
};

string jsonString = actionMappings["Get Patients"]();

This approach does require that all the methods return the same type and accept the same parameters.

Handling method parameters

Suppose that the methods all accept a string parameter and return a string, e.g. like this:

public sealed class Patient
{
    public string GetPatient(string patientId)
    {
        return "";
    }
}

Then you could use Func<string, string> for the dictionary values, like so:

var patient = new Patient();

Dictionary<string, Func<string, string>> actionMappings = new ()
{
    ["Get Patient"] = patId => patient.GetPatient(patId)

    // Etc
};

string jsonString = actionMappings["Get Patient"]("Pat ID");
Related