在运行时之前不知道反序列化对象

时间:2015-10-14 13:39:21

标签: c# generics deserialization

我已经浏览了Stack Overflow,并了解我计划实现的内容是不可能的,因为泛型在编译时是强类型的。但是,希望如果我能解释我想要的结果,有人可以指出我不同的道路。

我有一个从数据库中检索的typename和一些xml。为简单起见,它们如下:

string xml = @"<?xml version=\"1.0\"?><Car xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">  <Name>Vauxhall</Name></Car>";
string classname = "Demo.Car";

我最终想做的是拥有一个汽车对象,以便将其传递给显示汽车的表格。但是,可以表示一小部分固定的对象。

我知道我可以拥有以下内容,但希望有一个更优雅的解决方案:

switch(classname)
{
  case "Demo.Car":
    // deserialise into a car object and call method taking a car
    break;
  case "System.Collections.Generic.List<Demo.Car>":
    // deserialise into a list of car objects and call method taking a car
    break;
  case "Demo.Person":
    // deserialise into a car object and call method taking a car
    break;  
  //      and so on
}

我无法控制的事情:

  • .Net版本(我在4.0上)
  • 我从数据库收到的内容

我能控​​制什么

  • 其他所有

我知道人们会问我为什么要这样做。基本上,我们在消息总线上有几个主题的消息。有一个组件可以捕获来自众多主题的已接收消息,并将有效负载保存到我前面提到的表中。这些消息不是持久的(也不是它们),可以被认为是对任何侦听器而不是队列的广播。我必须在加载用户界面时检索消息的历史记录。

编辑1:

有关信息,以下是我希望做的,但正如顶部所解释的,我知道这是不可能的:

Type t = Type.GetType(classname);
var myCarObj = Serializer.FromXmlString<t>(xml); 
// Serializer is a utility class we have. it only wraps the System.Xml.Serialization

1 个答案:

答案 0 :(得分:1)

您可以使用字典将classname映射到相应的类型:

var map = new Dictionary<string, Type>
{
   { "Demo.Car", typeof(Car) },
   { "Demo.Person", typeof(Person) },
   ...
}

var serializer = new XmlSerializer(map[classname]);
using (var reader = new StringReader(xml))
{
   var result = serializer.Deserialize(reader);
   ...
}