我正在尝试泛型,我有这个(不那么)创建XMLSerializer类的好主意。拼凑在一起的代码如下:
public class Persist<T>
{
private string _path;
public Persist(string path) {
this._path = path;
}
public void save(T objectToSave)
{
XmlSerializer s = new XmlSerializer(typeof(T));
TextWriter w = new StreamWriter(this._path);
try { s.Serialize(w, objectToSave); }
catch (InvalidDataException e) { throw e; }
w.Close(); w.Dispose();
}
public T load()
{
XmlSerializer s = new XmlSerializer(typeof(T));
TextReader r = new StreamReader(this._path);
T obj;
try { obj = (T)s.Deserialize(r); }
catch (InvalidDataException e) { throw e; }
r.Close(); r.Dispose();
return obj;
}
}
问题在于:它在Persist<List<string>>
或Persist<List<int>>
上正常工作,但在Persist<List<userObject>>
或任何其他自定义(但可序列化)对象上无效。 userObject
本身只是一个包含两个{get; set;}属性的类,我之前已将其序列化。
我不确定我的Persist类(泛型),XML序列化代码或其他地方是否存在问题:(非常感谢帮助〜
编辑:
userObject的代码
public class userObject
{
public userObject(string id, string name)
{
this.id = id;
this.name = name;
}
public string id { get;private set; }
public string name { get;set; }
}
答案 0 :(得分:2)
在我看来,您的代码应该正常工作 - 即使它确实存在一些缺陷。
编辑: 您的userObject
课程不可序列化。 Xml序列化仅适用于具有公共无参数构造函数的类型 - 当前类不起作用。此外,您应该真的重写您的代码,以避免显式调用.Close()
或.Dispose()
,而是在可能的情况下更喜欢using
- 因为您可能会获得随机文件如果在序列化期间的任何时候锁定,则会发生错误,并且您的方法会因异常而终止 - 因此不会调用.Dispose()
。
就个人而言,我倾向于使用just-for-serialization对象层次结构,它只是存储在xml中的数据的容器,并且避免任何行为 - 特别是副作用。然后你可以使用一个简单的小基类来实现这一点。
我在项目中使用的内容如下:
public class XmlSerializableBase<T> where T : XmlSerializableBase<T>
{
static XmlSerializer serializer = new XmlSerializer(typeof(T));
public static T Deserialize(XmlReader from) { return (T)serializer.Deserialize(from); }
public void SerializeTo(Stream s) { serializer.Serialize(s, this); }
public void SerializeTo(TextWriter w) { serializer.Serialize(w, this); }
public void SerializeTo(XmlWriter xw) { serializer.Serialize(xw, this); }
}
...将序列化程序缓存在静态对象中,并简化了使用(在调用位置不需要通用的类型参数。
使用它的真实课程:
public class ArtistTopTracks {
public string name;
public string mbid;//always empty
public long reach;
public string url;
}
[XmlRoot("mostknowntracks")]
public class ApiArtistTopTracks : XmlSerializableBase<ApiArtistTopTracks> {
[XmlAttribute]
public string artist;
[XmlElement("track")]
public ArtistTopTracks[] track;
}
示例序列化调用:
using (var xmlReader = XmlReader.Create([...]))
return ApiArtistTopTracks.Deserialize(xmlReader);
//[...]
ApiArtistTopTracks toptracks = [...];
toptracks.SerializeTo(Console.Out);
答案 1 :(得分:1)
您的代码失败的原因可能有很多:在遇到问题时,此文本特别有用:Troubleshooting Common Problems with the XmlSerializer。也许你的用户对象中有一些类型层次结构,并且序列化程序不知道它?