c#serialize对象树

时间:2016-01-07 12:29:12

标签: c# xml serialization

我有应用程序,必须包含地图。为了实现这个任务,我创建了一些类:

1. ICoordinate
2. GpsCoordinateDeg
3. GpsCoordinateDegMinSec

一个接口和两个实现它的类:

public void GetObjectData(SerializationInfo, StreamingContext)

所有这些都实现了ISerialization接口并具有<?xml version="1.0"?> <Map xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />方法。

我想将我的地图保存在文件中,并且我意识到其中一种序列化方法,但它不起作用 - 我得到了无效的xml文件:

[Serializable] class Map : ISerializable { ... public void saveInFile(string filepath) { Serializer serializer = new Serializer(); serializer.SerializeObject(this, filepath); } ... }

我在此代码中使用我的类进行序列化:

Serializer

这是我class Serializer { public void SerializeObject<T>(T serializableObject, string fileName) { if (serializableObject == null) { return; } try { XmlDocument xmlDocument = new XmlDocument(); XmlSerializer serializer = new XmlSerializer(serializableObject.GetType()); using (MemoryStream stream = new MemoryStream()) { serializer.Serialize(stream, serializableObject); stream.Position = 0; xmlDocument.Load(stream); xmlDocument.Save(fileName); stream.Close(); } } catch (Exception ex) { //Log exception here } } public T DeSerializeObject<T>(string fileName) { if (string.IsNullOrEmpty(fileName)) { return default(T); } T objectOut = default(T); try { string attributeXml = string.Empty; XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(fileName); string xmlString = xmlDocument.OuterXml; using (StringReader read = new StringReader(xmlString)) { Type outType = typeof(T); XmlSerializer serializer = new XmlSerializer(outType); using (XmlReader reader = new XmlTextReader(read)) { objectOut = (T)serializer.Deserialize(reader); reader.Close(); } read.Close(); } } catch (Exception ex) { //Log exception here } return objectOut; } } 的代码:

   - ['bf', "if(or(tf(item_name,'with'),tf(item_name,'without')),-5,0)"]

问题出在哪里?

2 个答案:

答案 0 :(得分:2)

由于我不知道你的poco课程的完整实现,我建议你进一步了解你的GPSPoint课程:

  

GPSPoint(包含两个ICoordinate对象)

您无法序列化界面。问题是接口是不透明的类型。序列化器无法知道要写出什么,更重要的是当需要序列化时要创建什么。

您可以查看StackOverflow中的“序列化接口”字幕。我希望它有所帮助。

答案 1 :(得分:0)

由于它严重依赖于对象装箱和拆箱,因此很难用于序列化的泛型。

我这样做并不依赖于实施ISerializable,而是依赖于谨慎使用属性。

使用[Serializable()], [XmlType(AnonymousType=true)], [XmlRoot(Namespace="", IsNullable=false)]装饰下面的每个班级。枚举代​​表坐标类型。从这些类中派生您现有的类。标记您不希望在派生类中使用[XmlIgnore]序列化的属性。在Coordinate下面设置ICoordinate

public partial class Location {
    [XmlElement]
    public GPSPoint GPSPoint { get; set; }
    [XmlElement]
    public ImagePoint ImagePoint { get; set; }
}

public partial class GPSPoint {
    [XmlElement(ElementName = "Coordinate", Order = 0)]
    public Coordinate Coordinate1 {get; set; }
    [XmlElement(Order=1, ElementName="Coordinate")]
    public Coordinate Coordinate2 {get;set;}
}

public partial class Coordinate {        
    [XmlAttribute()]
    public ICoordinateType type {get;set;}
}

[Serializable]
public enum ICoordinateType {        
    /// <remarks/>
    GpsCoordinateDegMinSec,        
    /// <remarks/>
    GpsCoordinateDeg,
}

  public partial class Map {
    [XmlElement(Order=0, IsNullable=true)]
    public object Image { get; set; }        
    /// <remarks/>
    [XmlElement(ElementName="Location", Order = 1)]
    public Location Location1 {get; set; }        
    /// <remarks/>
    [XmlElement(ElementName = "Location", Order = 2)]
    public Location Location2 {get; set; }
}

这已经过测试并正在运行:

    var tc1 = new xyz.Coordinate () {type = xyz.ICoordinateType.GpsCoordinateDeg};
    var tc2 = new xyz.Coordinate () {type = xyz.ICoordinateType.GpsCoordinateDegMinSec};
    var l1 = new xyz.Location() {
        GPSPoint = new xyz.GPSPoint() { Coordinate1 = tc1, Coordinate2 = tc2 },
                ImagePoint = new xyz.ImagePoint() { x = 0, y = 0 } };

        xyz.Map m = new xyz.Map() {
            Image = null, 
            Location1 = l1,
            Location2 = new xyz.Location() {
                GPSPoint = new xyz.GPSPoint() {
                    Coordinate1 = tc1, Coordinate2 = tc2 },
                ImagePoint = new xyz.ImagePoint() { x = 1, y = 2 }
            } };

       XmlSerializer xs = new XmlSerializer(typeof(Map));
       using (var fs = File.Create("map.xml") ) { xs.Serialize(fs, m); }