c#序列化对象树
我有一个应用程序,它必须包含地图。为了实现此任务,我创建了一些类:c#序列化对象树,c#,xml,serialization,C#,Xml,Serialization,我有一个应用程序,它必须包含地图。为了实现此任务,我创建了一些类: 1. Map (contains Image and two objects of Location class) 2. GPSPoint (contains two objects of ICoordinate) 3. ImagePoint (contains two int variables) 4. Location (contains GPSPoint and ImagePoint) 一个接口,两个类,实现了: 1.
1. Map (contains Image and two objects of Location class)
2. GPSPoint (contains two objects of ICoordinate)
3. ImagePoint (contains two int variables)
4. Location (contains GPSPoint and ImagePoint)
一个接口,两个类,实现了:
1. ICoordinate
2. GpsCoordinateDeg
3. GpsCoordinateDegMinSec
它们都实现了ISerialization接口,并具有public void GetObjectData(SerializationInfo,StreamingContext)
方法
我想将我的地图保存在文件中,我实现了其中一种序列化方法,但它不起作用-我得到了无效的xml文件:
我在以下代码中使用我的类进行序列化:
[Serializable]
class Map : ISerializable {
...
public void saveInFile(string filepath) {
Serializer serializer = new Serializer();
serializer.SerializeObject(this, filepath);
}
...
}
这是我的序列化程序的代码
:
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;
}
}
类序列化程序{
public void SerializeObject(T serializableObject,字符串文件名){
如果(serializableObject==null){return;}
试一试{
XmlDocument XmlDocument=新的XmlDocument();
XmlSerializer serializer=新的XmlSerializer(serializableObject.GetType());
使用(MemoryStream stream=new MemoryStream()){
serializer.Serialize(流,serializableObject);
流位置=0;
加载(流);
xmlDocument.Save(文件名);
stream.Close();
}
}捕获(例外情况除外){
//此处记录异常
}
}
公共T反序列化对象(字符串文件名){
if(string.IsNullOrEmpty(fileName)){返回默认值(T);}
T objectOut=默认值(T);
试一试{
string attributeXml=string.Empty;
XmlDocument XmlDocument=新的XmlDocument();
加载(文件名);
字符串xmlString=xmlDocument.OuterXml;
使用(StringReader读取=新的StringReader(xmlString)){
类型outType=类型of(T);
XmlSerializer serializer=新的XmlSerializer(outType);
使用(XmlReader=新的XmlTextReader(读取)){
objectOut=(T)序列化程序。反序列化(读取器);
reader.Close();
}
read.Close();
}
}捕获(例外情况除外){
//此处记录异常
}
退出;
}
}
问题出在哪里?由于我不知道poco类的完整实现,我建议您进一步查看GPSPoint类: GPSPoint(包含两个图标坐标对象) 不能序列化接口。问题在于接口是不透明类型。序列化程序无法知道要写什么,更重要的是,当它需要将内容序列化回来时,要创建什么
您可以查看StackOverflow中的“序列化接口”-过账。我希望它能有所帮助。使用序列化的泛型是个坏主意,因为它严重依赖于对象装箱和拆箱 我这样做的方式并不依赖于实现
ISerializable
,而是依赖于仔细使用属性
用[Serializable()],[XmlType(AnonymousType=true)],[XmlRoot(Namespace=”“,IsNullable=false)]装饰下面的每个类。
。枚举表示坐标类型。从这些类派生现有类。标记不希望在派生类中使用[XmlIgnore]
序列化的属性。使下面的坐标
实现您的图标坐标
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; }
}
如果类具有由复杂类型构成的属性,则可能需要将其类型传递给序列化程序too@Alex,我编辑jop posting来解释这些类是如何相互通信的。在
SerializeObject
函数中,除了传入的参数外,您从不使用T
,如果使用T
防止装箱,则可以让函数接受对象
,该值将在序列化程序中装箱代码>呼叫。另外,如果您只是将文件流
直接传递给序列化
,而不是内存流
,则可以在该函数中节省大量的工作。
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); }