我有一个包含对象集合的类。集合中的对象是同一类的后代。 A类是基类,B类和C类继承自A类.B和C各有一些不同的成员。该系列是LIst系列。
我想序列化包含该集合的类。如何将不同的类归因于能够序列化和反序列化xml文件?
谢谢, 罗伯特
答案 0 :(得分:3)
[Serializable]
属性与XML序列化无关。 XML序列化程序使用public getter AND setter序列化属性。此外,您必须通过将Type[]
额外参数传递给序列化程序ctor或添加[XmlInclude(typeof(B))]
和{,向XML序列化程序告知可以使用的额外类型,静态不知道的类型。 {1}}
编辑:
以下代码:
[XmlInclude(typeof(C))]
生成xml:
[XmlInclude(typeof(B))]
[XmlInclude(typeof(C))]
public class A
{
public int Value;
public A() { }
public A(int i) { Value = i; }
}
public class B : A
{
public double DoubleValue;
public B() { }
public B(int i, double d) : base(i) { DoubleValue = d; }
}
public class C : A
{
public string StringValue;
public C() { }
public C(int i, string s) : base(i) { StringValue = s; }
}
public class Container
{
public List<A> Items;
public Container()
{
Items = new List<A>();
}
}
class Program
{
static void Main(string[] args)
{
Container container = new Container();
container.Items.Add(new B(0, 1.3d));
container.Items.Add(new B(1, 0.37d));
container.Items.Add(new C(2, "c"));
using (System.IO.StreamWriter writer = new System.IO.StreamWriter(@"C:\TEMP\Container.xml"))
{
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Container));
serializer.Serialize(writer, container);
}
}
}
答案 1 :(得分:0)
您可以使用XmlSerialization或DataContract(或更“原始”的实现),请参阅:http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/
至于序列化:您只需要标记要序列化的类,因此您需要标记B类和C类,但不需要标记A类。
但是我建议你将A类标记为可序列化,因此让你和其他程序员更清楚这个类支持序列化。
答案 2 :(得分:-1)
您不需要将类属性设置为使用Xml序列化:
using System;
using System.IO;
using System.Xml.Serialization;
/* Three classes are included here. Each one will
be used to create three XmlSerializer objects. */
public class Instrument
{
public string InstrumentName;
}
public class Player
{
public string PlayerName;
}
public class Piece
{
public string PieceName;
}
public class Test
{
public static void Main()
{
Test t = new Test();
t.GetSerializers();
}
public void GetSerializers()
{
// Create an array of types.
Type[]types = new Type[3];
types[0] = typeof(Instrument);
types[1] = typeof(Player);
types[2] = typeof(Piece);
// Create an array for XmlSerializer objects.
XmlSerializer[]serializers= new XmlSerializer[3];
serializers = XmlSerializer.FromTypes(types);
// Create one Instrument and serialize it.
Instrument i = new Instrument();
i.InstrumentName = "Piano";
// Create a TextWriter to write with.
TextWriter writer = new StreamWriter("Inst.xml");
serializers[0].Serialize(writer,i);
writer.Close();
}
}
要使用集合,您可以按如下方式对其进行序列化:
using System;
using System.IO;
using System.Collections;
using System.Xml.Serialization;
public class Test{
static void Main(){
Test t = new Test();
t.SerializeCollection("coll.xml");
}
private void SerializeCollection(string filename){
Employees Emps = new Employees();
// Note that only the collection is serialized -- not the
// CollectionName or any other public property of the class.
Emps.CollectionName = "Employees";
Employee John100 = new Employee("John", "100xxx");
Emps.Add(John100);
XmlSerializer x = new XmlSerializer(typeof(Employees));
TextWriter writer = new StreamWriter(filename);
x.Serialize(writer, Emps);
}
}
public class Employees:ICollection{
public string CollectionName;
private ArrayList empArray = new ArrayList();
public Employee this[int index]{
get{return (Employee) empArray[index];}
}
public void CopyTo(Array a, int index){
empArray.CopyTo(a, index);
}
public int Count{
get{return empArray.Count;}
}
public object SyncRoot{
get{return this;}
}
public bool IsSynchronized{
get{return false;}
}
public IEnumerator GetEnumerator(){
return empArray.GetEnumerator();
}
public void Add(Employee newEmployee){
empArray.Add(newEmployee);
}
}
public class Employee{
public string EmpName;
public string EmpID;
public Employee(){}
public Employee(string empName, string empID){
EmpName = empName;
EmpID = empID;
}
}