假定有如下类:[Serializable]
public class Family
{
public Family()
{
} public Husband Male
{
get;
set;
} public Wife Female
{
get;
set;
}
}[Serializable]
public class Husband
{
public Wife Wife
{
get;
set;
}
}[Serializable]
public class Wife
{
public Husband Husband
{
get;
set;
}
}
我需要对Family进行序列化和反序列化操作,但出现了类交叉使用的情况,该如何来解决该问题?谢谢!!
public class Family
{
public Family()
{
} public Husband Male
{
get;
set;
} public Wife Female
{
get;
set;
}
}[Serializable]
public class Husband
{
public Wife Wife
{
get;
set;
}
}[Serializable]
public class Wife
{
public Husband Husband
{
get;
set;
}
}
我需要对Family进行序列化和反序列化操作,但出现了类交叉使用的情况,该如何来解决该问题?谢谢!!
解决方案 »
- c#接口调用时,验证信息错误,该怎么在soapheader里传用户名密码呢?
- 类库
- 如何不用Aessmbly,就可以实现反射
- 各位大虾帮忙解决一下一个菜鸟问题!
- 没分了后面补充上,请问如何让动态加载的dll自动执行它内部的某个函数?
- 【散分讨论】No.03-Asp.Net开发小技巧
- 请问DotNet里面有没有从Dll和Exe文件里面提取资源(string table等)的类可以用?
- 怎么用Char控件t绘制曲线图(不涉及数据库,最简单的那种)
- dev的CheckedListBox问题。
- 小弟,期末作业,增加学生信息那一块错在那了啊!帮帮小弟啊!
- C# 事件访问器
- 如何把数据库中的表格导入到treeview
[DataContract]
[XmlInclude(typeof(ChamberRecipePair))]
public class Sequence : SequenceHeader, IEquatable<Sequence>楼主加下 [XmlInclude(typeof(ChamberRecipePair))]类似这样的,
如果要在sequence里面用ChamberRecipePair类的话,你的也一样
这种XmlInclude我尝试过,貌似不行正在考虑着仅只对Husband进行序列化,而不对Wife进行序列化,在反序列化时,动态生成Wife
[Serializable]
public class Family
{
public Family()
{
}
public Guid Guid
{
get;
set;
}
public Husband Male
{
get;
set;
} public Wife Female
{
get;
set;
}
}[Serializable]
public class Husband
{
public Guid Guid
{
get;
set;
}
public Wife Wife
{
get;
set;
}
}[Serializable]
public class Wife
{
public Guid Guid
{
get;
set;
}
public Husband Husband
{
get;
set;
}
}
所以必须自定义Xml序列化方法来实现,让你的类继承接口IXmlSerializable,实现ReadXml和WriteXml方法。
序列化之前,必须定义一个局部的字典缓存,用来存放对象的引用。
就你的例子,我给你写一个通过IXmlSerializable的实现,大概要1小时左右的调试时间,请等待。
{
public static Dictionary<int, object> cache = new Dictionary<int, object>();
} public class Husband : IXmlSerializable
{
public Wife Wife
{
get;
set;
} #region IXmlSerializable 成员 public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
} public void ReadXml(System.Xml.XmlReader reader)
{
if (reader.IsEmptyElement)
return;
XmlSerializer wifeSerializer = new XmlSerializer(typeof(Wife));
int hashcode = int.Parse(reader.GetAttribute("HashCode"));
SerCache.cache.Add(hashcode, this);
reader.Read();
hashcode = int.Parse(reader.GetAttribute("HashCode"));
if (SerCache.cache.Keys.Contains(hashcode))
{
Wife = (Wife)SerCache.cache[hashcode];
}
else
{
Wife = (Wife)wifeSerializer.Deserialize(reader);
}
} public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartAttribute("HashCode");
writer.WriteValue(this.GetHashCode());
writer.WriteEndAttribute();
if (SerCache.cache.Keys.Contains(this.GetHashCode()))
return;
SerCache.cache.Add(this.GetHashCode(), null);
XmlSerializer wifeSerializer = new XmlSerializer(typeof(Wife));
wifeSerializer.Serialize(writer, Wife);
} #endregion
} public class Wife : IXmlSerializable
{
public Husband Husband
{
get;
set;
} #region IXmlSerializable 成员 public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
} public void ReadXml(System.Xml.XmlReader reader)
{
if (reader.IsEmptyElement)
return;
XmlSerializer wifeSerializer = new XmlSerializer(typeof(Husband));
int hashcode = int.Parse(reader.GetAttribute("HashCode"));
SerCache.cache.Add(hashcode, this);
reader.Read();
hashcode = int.Parse(reader.GetAttribute("HashCode"));
if (SerCache.cache.Keys.Contains(hashcode))
{
Husband = (Husband)SerCache.cache[hashcode];
}
else
{
Husband = (Husband)wifeSerializer.Deserialize(reader);
}
} public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartAttribute("HashCode");
writer.WriteValue(this.GetHashCode());
writer.WriteEndAttribute();
if (SerCache.cache.Keys.Contains(this.GetHashCode()))
return;
SerCache.cache.Add(this.GetHashCode(), null);
XmlSerializer wifeSerializer = new XmlSerializer(typeof(Husband));
wifeSerializer.Serialize(writer, Husband);
} #endregion
}如果你用XmlSerializer序列化的话,将得到如下形式的递归表现,重复会停止:
<?xml version="1.0" encoding="utf-8"?>
<Husband HashCode="511887">
<Wife HashCode="37621475">
<Husband HashCode="511887" />
</Wife>
</Husband>注意:每次序列化和反序列化之前,必须调用“SerCache.cache.Clear();”将上次可能产生的序列化缓存清空(你也可以在序列化或反序列化结束的时候这么做)。
非常感谢我现在一板一眼地写XmlDocument,不使用Xml序列化了,其实效果差不多,使用的想法与您提出的是一样的,有一个缓存队列,先实例化所有的对象,然后遍历一遍后再进行赋值。再次感谢!