call a Method with parameters got from generic Method


I have a class storing the name of a WS method to call and the type and value of the only parameter that service receives (it will be a collection of parameters but lets keep it simple for the example):

public class MethodCall
  public string Method { get; set; }
  public Type ParType { get; set; }
  public string ParValue { get; set; }
  public T CastedValue<T>()
    return (T)Convert.ChangeType(ParValue, ParType);

I have a method that takes the method name and the parameters and using reflection calls the method and returns the result. That one works fine when i use it like this:

callingclass.URL = url;
callingclass.Service = serviceName;
object[] Params = { (decimal)1 };
callingclass.CallMethod("Hello", Params);

But my type, decimal in the example, is given in the instance of MethodCall. So if i have this code:

MethodCall call = new MethodCall();
call.Method = "Hello";
call.ParType = typeof(decimal);
call.ParValue = "1";

Option 1, doesn't compile:

object[] Params = { (call.ParType)call.ParValue }; //Compilation error: The type or namespace name 'call' could not be found (are you missing a using directive or an assembly reference?)

Option 2, doesn't compile neither:

object[] Params = { call.CastedValue<call.ParType>() }; //Compilation error: Cannot implicitly convert type 'call.ParType' to 'object'

Option 3, using reflection, compiles but doesn't work when calling the service:

object[] Params = { typeof(MethodCall).GetMethod("CastedValue").MakeGenericMethod(call.ParType).Invoke(this, null) };

callingclass.CallMethod(call.Method, Params);

The exception is: ConnectionLib.WsProxyParameterExeption: The parameters for the method 'TestService.Hello' in URL 'http://localhost/MyTestingService/' are wrong.

So can someone point me the right way to make this work?



If you're calling the method with reflection, that's going to effectively end up casting anyway. You don't have either the speed benefits or compile-time type safety benefits of generics here - I don't really think you're doing yourself any favours by using it.

Generics are useful when you do know the type statically at compile-time, at least somewhere. The fact that you've got a ParType property really goes against the point of generics.

By : Jon Skeet

You can't just cast a string ("1") to a decimal, and even if you could I doubt that the generic version would know about it... it would try to do a reference-preserving cast, where-as you'd need an operator conversion (they share syntax in C#, but are very different).

So basically, I think Convert.ChangeType is your only sensible option here.

I do have some code that will allow you to use operator conversion via generics, but there is no operator conversion between string and decimal, so it wouldn't help.

This video can help you solving your question :)
By: admin