直到运行时才知道反序列化对象

本文关键字:反序列化 对象 运行时 | 更新日期: 2023-09-27 18:17:51

我看了一下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";

我最终想做的是有一个car对象,这样我就可以把它传递给一个显示Cars的表单。然而,有一小部分固定数量的对象可以被表示。

我知道我可以有像下面这样的东西,但有一个模糊的希望,有一个更优雅的解决方案:

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

直到运行时才知道反序列化对象

您可以使用dictionary将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);
   ...
}