我有一个小问题困扰了我几天。我正在为虚拟赛车联赛编写一种管理工具。 我想将所有数据保存到单个xml文件中,以便可以轻松地从多个方进行访问。 但是,由于xml-serializer的限制,id必须将我所有的类都公开。为此,我编写了一个界面 通过这种方式,我想将原始的管理对象(具有所有功能)转换为包含要进行xml序列化的对象的原始数据。
为了能够跟踪谁创建/更改了所有相关内容,需要持有“ ChangeNotification”字段。 为此,我使用这些字段创建了一个基类,并从中派生了我的容器类。
现在问题来了:如果我只序列化其中一部分,那么一切都很好。但是,一旦我序列化了一个包含另一个从相同基数派生的对象的对象, 我的“ CreateChangeNotification”将仅出现在顶部的对象中。
我不知道为什么这样做,因为显然有两个实例保存在对象中,同时具有不同的值。
很抱歉,很长的代码段,但这就是我需要重新创建问题的地方,并且似乎每次使用此结构都会发生。
[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>
您可以看到Comment的Create元素只是丢失。
答案 0 :(得分:0)
我发现了问题。通过界面添加注释对象时,changenotification不会被带走并丢失。 在我完整的代码中,如果我使用反射来自动设置所有属性,则问题会更加隐蔽。 但是,我只查看主接口类型,而不是所有已实现的接口类型。 我更改了代码,现在可以正常工作了。 谢谢您的支持。