内部的には、docsによると、状態サーバーはBinaryFormatter
複雑な型をシリアル化するために使用します。 としてマークされたクラスまたは構造体のBinaryFormatter
すべてのパブリックおよびプライベートフィールド[Serializable]
(プロパティではありません!) をシリアル化します。しかしXmlDocument
、あなたが指摘したように、 はそれほどマークされていないため、 ですぐにシリアル化することはできませんBinaryFormatter
。
XmlDocument
ただし、文字列 (ドキュメントが表す XML 自体) との間で簡単に変換できます。したがって、XmlDocument
フィールドが を実装する型に含まれている場合ISerializable
、GetObjectData()
対応する XML 文字列をシリアライゼーション ストリーム内に単純に格納できます。次に、対応するシリアル化コンストラクターが XML 文字列を抽出し、XmlDocument
.
ISerializable
既存のクラスへの実装は時間がかかる可能性があるため、目的を達成する最も簡単な方法は、XML ドキュメントに小さなシリアル化ラッパー構造体を導入することです。
[Serializable]
public struct XmlDocumentSerializationWrapper : ISerializable
{
public static implicit operator XmlDocumentSerializationWrapper(XmlDocument data) { return new XmlDocumentSerializationWrapper(data); }
public static implicit operator XmlDocument(XmlDocumentSerializationWrapper wrapper) { return wrapper.XmlDocument; }
private readonly XmlDocument xmlDocument;
public XmlDocument XmlDocument { get { return xmlDocument; } }
public XmlDocumentSerializationWrapper(XmlDocument xmlDocument)
{
this.xmlDocument = xmlDocument;
}
public XmlDocumentSerializationWrapper(SerializationInfo info, StreamingContext context)
{
var xml = (string)info.GetValue("XmlDocument", typeof(string));
if (!string.IsNullOrEmpty(xml))
{
xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
}
else
{
xmlDocument = null;
}
}
#region ISerializable Members
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (XmlDocument != null)
{
var xml = XmlDocument.OuterXml;
info.AddValue("XmlDocument", xml);
}
else
{
info.AddValue("XmlDocument", (string)null);
}
}
#endregion
}
XmlDocument
次に、シリアル化するクラスで、フィールド (および自動実装されたプロパティ) をラッパー構造体フィールドに置き換えます。
[Serializable]
public class TestClass
{
XmlDocumentSerializationWrapper doc;
public XmlDocument Document { get { return doc; } set { doc = value; } }
}
構造体の暗黙の演算子は、ラッパーとの間の自動変換を処理します。