Daniel Kaschel

Daniel Kaschel

  • NA
  • 3
  • 308

Calling a method by name with parameters (or build like sql)

Jan 21 2016 12:35 PM
.Net Version 4.5.1
 
Very Brief Background
I have a console application where the user enters a function and parameters. Rather than adding supported functions to a dictionary of some kind, I'd like to just have it call the method by name, using the method signature to validate the parameters. I can gather all the information I need in theory, but can't figure out how to CALL the expression.
 
I think I know why--it's because I can't figure out how to coerce my parameters into a form the Expression.Call line will accept. I tried using the ParameterExpression class, but it doesn't seem to contain the values, only the types and names.
 
What I Want to Do 
  1. /// <summary>  
  2. /// Call a method in this class instance by name and parameters  
  3. /// </summary>  
  4. /// <param name="methodName"></param>  
  5. /// <param name="args"></param>  
  6. /// <returns></returns>  
  7. public void Execute(string methodName, object[] args)  
  8. {  
  9.     //get method we will be calling  
  10.     MethodInfo method = GetMethodByName(methodName);  
  11.   
  12.     //validate & retrieve parameters based on the method signature         
  13.     object[] parameters;  
  14.     if (!GetAndValidateParams(  
  15.                 method.GetParameters().Select(pd => pd.ParameterType).ToArray(),  
  16.                 args,  
  17.                 out parameters))  
  18.         return//exit on failed validation of parameters  
  19.   
  20.     //call method using signature -- this is where I'm getting an error  
  21.     Expression.Call(method, parameters);  
  22. }  
 I would also be happy with the ability to "assemble" a method call, like in this pseudocode:
  1. MethodCall mc = new MethodCall(methodInfo);  
  2. mc.ClassInstance = this;  
  3. mc.Parameters.AddRange(parameters);  
  4. mc.Execute();  
Thank you in advance for any help or guidance you can provide!
 
Daniel
 
Just in Case: The Validation Method
  1. //validates that types are as expected. Only accepts string, int and decimal  
  2. private bool GetAndValidateParams(Type[] expected, object[] args, out object[] convertedArgs)  
  3. {  
  4.     Console.Write("Validating parameters...");  
  5.   
  6.     //check for any unsupported types  
  7.     convertedArgs = null;  
  8.     Type[] supportedTypes = new Type[] { typeof(decimal), typeof(string), typeof(int) };  
  9.     if (expected.Any(t => !supportedTypes.Any(st => t == st))) return false;  
  10.       
  11.     if (expected == nullreturn false;  
  12.     if (expected.Count() == 0 && (args == null || args.Count() == 0))  
  13.     {  
  14.         Console.Write("Success.\r\n");  
  15.         return true;  
  16.     }  
  17.     convertedArgs = new object[args.Count()];  
  18.     for (int x = 0; x < expected.Count(); x++)  
  19.     {  
  20.         //check to make sure there are args left  
  21.         if (x > (args.Count() - 1)) return false;  
  22.   
  23.         //if we have an arg and an expectation, check them  
  24.         try { convertedArgs[x] = Convert.ChangeType(args[x], expected[x]); }  
  25.         catch {return false;}  
  26.     }  
  27.   
  28.     //If we got here, everything was validated successfully  
  29.     Console.Write("Success.\r\n");  
  30.     return true;  
  31. }  
 

Answers (1)