我有一个类,用于存储要调用的WS方法的名称以及服务接收的唯一参数的类型和值(它将是参数的集合,但是让这个示例保持简单):
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);
}
}
我有一个方法,它接受方法名称和参数,并使用反射调用方法并返回结果。当我像这样使用它时,那个工作正常:
callingclass.URL = url;
callingclass.Service = serviceName;
object[] Params = { (decimal)1 };
callingclass.CallMethod("Hello", Params);
但是我的类型,例子中的十进制,是在MethodCall的实例中给出的。所以,如果我有这个代码:
MethodCall call = new MethodCall();
call.Method = "Hello";
call.ParType = typeof(decimal);
call.ParValue = "1";
选项1,不编译:
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?)
选项2,既不编译也不编译:
object[] Params = { call.CastedValue<call.ParType>() }; //Compilation error: Cannot implicitly convert type 'call.ParType' to 'object'
选项3,使用反射,编译但在调用服务时不起作用:
object[] Params = { typeof(MethodCall).GetMethod("CastedValue").MakeGenericMethod(call.ParType).Invoke(this, null) };
callingclass.CallMethod(call.Method, Params);
例外是: ConnectionLib.WsProxyParameterExeption:URL“http://localhost/MyTestingService/”中方法“TestService.Hello”的参数错误。
那么有人能指出我正确的方法吗?
由于
答案 0 :(得分:2)
抱歉,我应该补充说,如果我这样做:
object[] Params = { Convert.ChangeType(call.ParValue, call.ParType)};
它工作正常,但调用对象中泛型方法的重点是避免使用时的转换。
答案 1 :(得分:2)
你不能只是将一个字符串(“1”)转换为十进制,即使你可以怀疑泛型版本会知道它...它会尝试做一个参考保持演员表,其中 - 你需要一个运算符转换(它们在C#中共享语法,但是非常不同)。
所以基本上,我认为Convert.ChangeType是你唯一明智的选择。
我确实有some code允许您通过泛型使用运算符转换,但字符串和小数之间没有运算符转换,所以它没有帮助。
答案 2 :(得分:2)
如果你用反射来调用方法,那么无论如何都会有效地结束。你没有这里的仿制药的速度优势或编译时类型安全优势 - 我真的不认为你通过使用它来为自己做任何好处。
当 在编译时静态地知道类型,至少某处时,泛型非常有用。你有一个ParType
属性的事实真的违背了泛型。