我遇到了我认为可能是我的代码设计的主要问题,我希望有人可以向我解释我将如何解决这个问题。
我有2个类,每个类都有另一个类的属性创建循环引用。我计划序列化这些类并使用XSLT格式化输出,但我假设由于循环引用而失败。
实施例
public class Book
{
public BookShop TheShop = new BookShop();
}
public class BookShop
{
list<Book> Books = new list<Book>();
}
因此,从这个例子中,每本书都会出现在书店中,每个书店都会有很多书。如果我序列化书店,它将序列化每本书,然后序列化书店等等。我应该怎么处理这个?
答案 0 :(得分:6)
使用属性标记TheShop
以防止其序列化。
[XmlIgnore]
使用默认序列化程序。
http://www.codeproject.com/KB/XML/GameCatalog.aspx
可能只是您示例的问题,而不是您的真实代码:不要使用公共字段,而是使用属性。我认为XmlSerializer
甚至没有序列化公共字段。
答案 1 :(得分:1)
将[XmlIgnore]
添加到TheShop
属性,以防止序列化。
然后,您可以在反序列化时手动设置它。
答案 2 :(得分:1)
最佳做法是让BookShop类实现一个接口(IBookShop),然后让Book类存储接口而不是具体类。您还应该将BookShop变成Book类中的属性:
public class Book
{
public Book(IBookShop bookShop)
{
TheStop = bookShop;
}
[XmlIgnore]
public IBookShop TheShop { get; set; }
}
public interface IBookShop
{
void SomeMethod();
}
public class BookShop : IBookShop
{
list<Book> Books = new list<Book>();
public void SomeMethod()
{
}
}
答案 3 :(得分:0)
如果您要使用System.Xml.Serialization.XmlSerializer
,则应使用TheShop
装饰System.Xml.Serialization.XmlIgnoreAttribute
:
public class Book
{
[System.Xml.Serialization.XmlIgnore]
public BookShop TheShop;
}
也就是说,假设BookShop
是您希望序列化的根对象。 MSDN
答案 4 :(得分:0)
首先,你需要检查这是否真的是一个问题。如果你有一本书时总是关心书店,并且你总是关心书店所有的书籍,那么将整个图表序列化是完全明智的。这不会导致无限循环,因为序列化使用标识符来指示对已经序列化的对象的引用(如果在 types <中使用循环引用对图进行XML序列化,则会出现错误/ strong>,但这是一个错误而不是XML序列化问题所固有的错误,因为可以解决它的事实证明,请参阅Why do I get a "System.StackOverflowException was unhandled " exception when serializing?。
所以,也许你根本不想在这里做任何事情,你就像你一样好。
否则,问题是 - 你想要序列化什么?到目前为止,大多数建议都是不对TheShop
属性进行序列化。这可能没问题,或者如果您以后需要访问该商店,则可能没用。
如果你有每种商店的某种标识符(id号,uri),那么你可能会记忆 - 访问TheShop
首先查看私有_theShop
是否为空,如果是是,根据该标识符将相关对象加载到_theShop
。然后你只需要序列化标识符,而不是完整的对象。
最后,如果您使用XSLT将输出格式化为其他规范(无论是用于显示XHTML还是其他规范),您可能会发现只需滚动自己的XML序列化就更简单了。虽然这在许多方面都是一项更复杂的任务,但序列化生成的XML对于重新格式化显示并不是特别方便,这可能意味着整体而言这种方式更简单。实际上,如果这是序列化的唯一原因(您永远不会从生成的XML中反序列化)那么它可能会容易得多,因为您只需要考虑显示所需的XML,而不必担心其他任何问题。因此,序列化可能不是最好的方法,而只是ToXml()
方法或另一个类中的WriteBookToXml()
方法。