使用.net反射创建的对象是否可以序列化?

时间:2009-12-05 16:54:37

标签: .net xml reflection serialization

是否可以序列化通过反射创建的对象?在尝试执行通过反射创建的对象的序列化时,我收到“无法将类型'对象'testNameSpace.ScreenClass'强制转换为'testNameSpace.ScreenClass'”的错误。错误没有意义,因为类型是相同的,所以演员应该是成功的。没有反射创建的对象的实例可以序列化OK。

修改 这是在我原来的帖子中没有正确呈现的代码

//Get the Assembly from file
 Assembly webAssembly = Assembly.LoadFile(@"C:\TestAssembly.exe");

 //Get the type from assembly
 Type screenType = webAssembly.GetType("testNameSpace.ScreenClass");

 //get the Constructor for the type (constructor does not take in parameters)
 ConstructorInfo ctor = screenType.GetConstructor(new Type[0]);

 //create an instance of the type
 object screen = ctor.Invoke(new object[] { });

 //get the "id" property of type
 PropertyInfo screenId = screenType.GetProperty("id");

 //populate the "id" property of the instance
 screenId.SetValue(screen, "1", null);

 Console.WriteLine("value of id property: " 
  + (string)screenId.GetValue(screen,null));

 //Attempt to serialize the instance of the object created through reflection
 try
 {
  FileStream fs = new FileStream("serialized.xml", FileMode.Create);
  XmlSerializer serializer = 
   new XmlSerializer(typeof(testNameSpace.ScreenClass));
  serializer.Serialize(fs, screen); //error occurs here
  fs.Close();
 }
 catch (Exception ex)
 {
  Console.WriteLine("Message: {0}\nInnerException: {1}\nStack Trace:\n{2}", 
   ex.Message, ex.InnerException.Message, ex.StackTrace);
 }

 //Now create instance of object without using reflection and serialize
 testNameSpace.ScreenClass screen2 = new testNameSpace.ScreenClass();
 screen2.id = "2";
 FileStream fs = new FileStream("serialized2.xml", FileMode.Create);
 XmlSerializer serializer 
  = new XmlSerializer(typeof(testNameSpace.ScreenClass));
 serializer.Serialize(fs, screen2);
 fs.Close();
 Console.WriteLine
  ("\nContents of serialized2.xml:\n" + File.ReadAllText("serialized2.xml"));

从控制台

运行时的输出
Message: There was an error generating the XML document.
InnerException: Unable to cast object of type 'testNameSpace.ScreenClass' to type 'testNameSpace.ScreenClass'.
Stack Trace:
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o, XmlSerializerNamespaces namespaces)
   at System.Xml.Serialization.XmlSerializer.Serialize(Stream stream, Object o)
   at Program.GetOneProperty() in C:\Code\Serialize.cs:line 96

Contents of serialized2.xml:
<?xml version="1.0"?>
<applicationScreensScreen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="2" />

1 个答案:

答案 0 :(得分:1)

Assembly.LoadFile()方法是你的问题,它在错误的上下文中加载程序集。装载环境有点难以理解,Suzanne Cook在她的博客中谈论它。当序列化程序需要类型时,它将使用Assembly.LoadFrom()并再次加载程序集。现在它发现不匹配,不同程序集中的类型永远不会相同。

LoadFile()仅在非常有限的情况下有用,如MSDN库文章的“备注”部分所述。您应该使用Assembly.LoadFrom()或Load()。更喜欢后者,因为它消除了从不同文件加载具有相同显示名称的程序集的可能性。如果这会导致问题,因为程序集不在程序的探测路径中(如果它存储在c:\中则不会),则实现AppDomain.AssemblyResolve事件处理程序以确保找到正确的文件。