[英]How do I invoke methods dynamically based on the actual runtime type?
I am receiving JSON from an outside source (with type info in it) that I deserialize with JSON.NET 我从外部源(其中包含类型信息)接收JSON,我使用JSON.NET反序列化
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.All;
//because the type info is included 'obj' will be of type Foo, Bar, Baz, etc
var obj = JsonConvert.DeserializeObject(jsonString, settings);
I also receive the type of command that I need to execute on the object (eg Send, Retrieve, Remove, etc). 我还收到了我需要在对象上执行的命令类型(例如Send,Retrieve,Remove等)。 I use this to invoke the correct method on a service. 我用它来调用服务上的正确方法。 The service defines its methods for each type in this format (note: I don't maintain the service, I just call it): 该服务以这种格式为每种类型定义其方法(注意:我不维护服务,我只是称之为):
///where T has an implementation for each type (Foo, Bar, etc)
T Send(T objToSend)
T Retrieve (T objToRet)
T Remove (T objToRemove)
so for example: 例如:
Foo f = service.Send(aFoo);
Bar b = service.Send(aBar);
Foo f2 = service.Retrieve(aFoo);
Bar b2 = service.Retrieve(aBar);
is there a more elegant way to do this other than a big switch statement and if-else blocks for every type? 除了一个大的switch语句和if-else块之外,还有更优雅的方法吗? This will work, but it seems really clunky and if we continue to add types it will only get clunkier 这样可行,但看起来真的很笨重,如果我们继续添加类型,它只会变得笨拙
switch(command){
case "Send":
if(obj is Foo){
service.Send((Foo)obj);
}
if(obj is Bar){
service.Send((Bar)obj);
}
if(obj is Baz){
service.Send((Baz)obj);
}
break;
case "Retrieve":
//etc...
case "Remove":
//etc...
}
thank you for any insight you can provide 感谢您提供的任何见解
You could use relfection to achieve this. 您可以使用relfection来实现此目的。 Given the following classes: 鉴于以下类别:
public class Bar
{
}
public class Foo
{
}
public class Service
{
public Bar Send(Bar objToSend)
{
Console.WriteLine("Send Bar");
return objToSend;
}
public Foo Send(Foo objToSend)
{
Console.WriteLine("Send Foo");
return objToSend;
}
}
Call the service in the following way: 以下列方式呼叫服务:
// This is the object we received and need to process
var obj = new Bar();
// This is the method we need to execute
string method = "Send";
// Initialize a new service and get its type
var service = new Service();
Type serviceType = service.GetType();
// Get the correct method by looking at the method name and the parameter type
MethodInfo methodInfo = serviceType.GetMethods().FirstOrDefault(x => x.Name == method && x.GetParameters()[0].ParameterType == obj.GetType());
// Invoke the method
object returnObj = methodInfo.Invoke(service, new object[] { obj });
If you care about performance at all, I recommend against this approach, and simply use a switch instead. 如果您完全关心性能,我建议不要使用这种方法,而只需使用开关。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.