【发布时间】:2018-11-16 06:17:46
【问题描述】:
我有一个小问题困扰了我好几天。我正在为虚拟赛车联盟编写一种管理工具。 我想将我的所有数据保存到一个 xml 文件中,以便可以轻松地从多方访问。 但是,由于 xml-serializer 的限制,id 必须公开我的所有类。为此我写了一个界面 我想通过它将我原来的管理对象(具有所有功能)转换为包含用于 xml 序列化的对象的原始数据。
为了能够跟踪谁创建/更改了某些相关内容,每个相关人员都需要保存一个“ChangeNotification”字段。 为此,我使用这些字段创建了一个基类,并且我的容器类是从该基类派生的。
现在问题来了:如果我只序列化其中的一部分,一切都可以正常工作。但是一旦我序列化一个包含另一个从同一基础派生的对象的对象, 我的“CreateChangeNotification”只会出现在顶部对象中。
我不明白它为什么这样做,因为它显然有两个实例保存在对象中,同时持有不同的值。
抱歉,sn-p 代码太长了,但这是我重新创建问题所需要的,而且似乎每次使用这种结构都会发生。
[Serializable()]
public class DataManagerXmlContainer<DataContainerType> : IDataManagerContainer
{
[XmlElement("Created")]
public ChangeNotificationXmlContainer created;
[XmlIgnore()]
public IChangeNotificationDataContainer Created { get => created; set => created = new ChangeNotificationXmlContainer(value); }
//[XmlElement("Changed")]
//public ChangeNotificationXmlContainer changed;
//[XmlIgnore()]
//public IChangeNotificationDataContainer LastChange { get => changed; set => changed = new ChangeNotificationXmlContainer(value); }
public DataManagerXmlContainer() { }
}
[Serializable()]
public class ReviewDataXmlContainer : DataManagerXmlContainer<IReviewDataContainer>, IReviewDataContainer
{
[XmlArray("CommentList")]
[XmlArrayItem("Comment")]
public List<ReviewCommentXmlContainer> comments = new List<ReviewCommentXmlContainer>();
[XmlIgnore()]
public ICollection<IReviewCommentDataContainer> Comments
{
get => comments.Cast<IReviewCommentDataContainer>().ToList();
set => comments = value.ToList().ConvertAll(x => new ReviewCommentXmlContainer(x));
}
public ReviewDataXmlContainer() { }
public ReviewDataXmlContainer(string authorID)
{
created = new ChangeNotificationXmlContainer(authorID, DateTime.Now);
}
public void AddComment(IReviewCommentDataContainer comment)
{
comments.Add(new ReviewCommentXmlContainer(comment));
}
}
[Serializable()]
public class ReviewCommentXmlContainer : DataManagerXmlContainer<IReviewCommentDataContainer>, IReviewCommentDataContainer
{
[XmlAttribute("author_id")]
public string AuthorAdminID { get; set; }
public string Text { get; set; }
public ReviewCommentXmlContainer() { }
public ReviewCommentXmlContainer(string authorID, string text)
{
created = new ChangeNotificationXmlContainer(authorID, DateTime.Now);
AuthorAdminID = authorID;
Text = text;
}
public ReviewCommentXmlContainer(IReviewCommentDataContainer dataContainer)
{
AuthorAdminID = dataContainer.AuthorAdminID;
Text = dataContainer.Text;
}
}
[Serializable()]
public class ChangeNotificationXmlContainer : IChangeNotificationDataContainer
{
[XmlAttribute("author_id")]
public string AuthorID { get; set; }
[XmlAttribute("time")]
public DateTime Time { get; set; }
public ChangeNotificationXmlContainer() { }
public ChangeNotificationXmlContainer(string id, DateTime time)
{
AuthorID = id;
Time = time;
}
public ChangeNotificationXmlContainer(IChangeNotificationDataContainer dataContainer)
{
AuthorID = dataContainer.AuthorID;
Time = dataContainer.Time;
}
}
public interface IChangeNotificationDataContainer
{
string AuthorID { get; set; }
DateTime Time { get; set; }
}
public interface IDataManagerContainer
{
IChangeNotificationDataContainer Created { get; set; }
}
public interface IReviewDataContainer : IDataManagerContainer
{
ICollection<IReviewCommentDataContainer> Comments { get; set; }
void AddComment(IReviewCommentDataContainer comment);
}
public interface IReviewCommentDataContainer : IDataManagerContainer
{
string AuthorAdminID { get; set; }
string Text { get; set; }
}
以及程序代码:
class Program
{
static void Main(string[] args)
{
IReviewCommentDataContainer comment = new ReviewCommentXmlContainer("12345", "This is a test");
Task.Delay(1000).Wait();
ReviewDataXmlContainer review = new ReviewDataXmlContainer("23456");
review.AddComment(comment);
XmlSerializer serializer = new XmlSerializer(typeof(ReviewDataXmlContainer));
TextWriter writer = new StreamWriter("Test.xml");
serializer.Serialize(writer, review);
//Task.Delay(-1).Wait();
}
}
这就是我的 xml 的样子:
<?xml version="1.0" encoding="utf-8"?>
<ReviewDataXmlContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Created author_id="23456" time="2018-11-16T06:56:16.5425819+01:00" />
<CommentList>
<Comment author_id="12345">
<Text>This is a test</Text>
</Comment>
</CommentList>
</ReviewDataXmlContainer>
正如你所见,评论的创建元素只是缺失了。
【问题讨论】:
-
这实际上并没有回答您的问题,但我不得不问 - 您是否考虑过其他持久性选项?如果你喜欢基于文件的为什么不sqlite.org/onefile.html。你最终可能会保留你的头发......
-
谢谢。我会调查一下。但是,该项目的主要目标是学习如何使用接口和序列化等。
-
当序列化一个继承另一个类的类时,你需要一个包含:[XmlInclude(type)]
-
谢谢,我稍后再试。
-
@jdweng:在研究 [xmlinclude] 时,我只发现了用于序列化派生类型的用法。在这种情况下,我希望它正确序列化它应该已经知道的基本类型的成员。在这种情况下我将如何使用 [xmlinclude]?
标签: c# xml serialization