【发布时间】:2019-10-21 01:18:25
【问题描述】:
我从外部源(其中包含类型信息)接收 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);
我还收到了我需要在对象上执行的命令类型(例如发送、检索、删除等)。我使用它在服务上调用正确的方法。服务以这种格式为每种类型定义其方法(注意:我不维护服务,我只是调用它):
///where T has an implementation for each type (Foo, Bar, etc)
T Send(T objToSend)
T Retrieve (T objToRet)
T Remove (T objToRemove)
例如:
Foo f = service.Send(aFoo);
Bar b = service.Send(aBar);
Foo f2 = service.Retrieve(aFoo);
Bar b2 = service.Retrieve(aBar);
除了每个类型的大 switch 语句和 if-else 块之外,还有更优雅的方法吗?这会起作用,但它看起来真的很笨拙,如果我们继续添加类型,它只会变得更笨拙
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...
}
感谢您提供的任何见解
【问题讨论】:
-
我猜
dynamic会起作用,但当然也有一些取舍。 -
可以修改
Foo,Bar吗?Send路由可以通过接口完成。对于路由命令类型,您仍然需要switch/case、if或带有键的东西(例如字典)。 -
如果你可以像 Sinatr 建议的那样使用接口,那将是最优雅的方式。否则,您可以使用反射。
-
在您的代码中是否还有其他地方需要将
Foo的引用输入为Foo并将Bar的引用输入为Bar?dynamic的运行时重载决议很诱人,但我可能只是通过反射来做到这一点。
标签: c# .net architecture