使用反射的c#反序列化

本文关键字:反序列化 反射的 | 更新日期: 2023-09-27 17:53:18

我有一个反序列化类的.dll。当我从项目中调用这个.dll或不使用反射时,它工作得很好。当我使用反射调用.dll时,我在反序列化的行上得到一个错误。我知道这是由于使用反射加载程序集时发生的隔离。想知道是否有人有任何修复或如何实现这一点的想法?顺便说一句,序列化工作得很好,只是反序列化不起作用。

我尝试了二进制和xml,下面是代码:

static public object SerializeLoad(string sFilename)
        {
            try
            {
                List<ElementTodo> _object = null;//ElementTodo _object = null;
                Stream stream = File.Open(sFilename, FileMode.Open);
                //BinaryFormatter bformatter = new BinaryFormatter();
                XmlSerializer bformatter = new XmlSerializer(typeof(ElementTodo), "ToDo");
                //_object = (_object.GetType())bformatter.Deserialize(stream);
                _object = (List<ElementTodo>)bformatter.Deserialize(stream);
                stream.Close();
                return _object;
            }
            catch(Exception e)
            {
                string error = e.Message;
                return null;
            }
        }

生成的XML如下:

& lt;

?xml version="1.0"?> 
  <ArrayOfElementTodo xmlns:xsi="w3.org/2001/XMLSchema-instance"; xmlns:xsd="w3.org/2001/XMLSchema"; xmlns="ToDo"> 
      <ElementTodo Title="a" content="aa" isDone="false" /> 
      <ElementTodo Title="b" content="bb" isDone="false" /> 
      <ElementTodo Title="c" content="cc" isDone="false" /> 
      <ElementTodo Title="d" content="dd" isDone="false" /> 
  </ArrayOfElementTodo>

使用反射的c#反序列化

我假设ElementTodo位于您的代码和使用反射加载的程序集都可以访问的程序集中?需要注意的是,加载的程序集正在使用相同的依赖程序集,并且不会加载新的副本。否则你会遇到一些有趣的错误,比如"对象X (ElementTodo类型)不是ElementTodo类型",因为加载了两个类型的副本。但是,如果没有关于具体错误的更多信息,很难确定这是您的问题。

如果这是你的问题,你可以通过强制程序集解析到已经加载的版本来解决它,像这样:

在你的启动代码的某处:

        //This is required because we load assemblies at runtime
        //If this is not used, there can be problems when Reflecting over Types
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
实现:

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        return AppDomain.CurrentDomain.GetAssemblies().
            FirstOrDefault(assembly => assembly.FullName == args.Name);
    }