特定の属性 (Dictionary や任意のクラスなど) を処理する必要がある場合は、IXmlSerialiableインターフェイスを実装できます。これにより、コーディングが冗長になりますが、自由度が高まります。
public class NetService : IXmlSerializable
{
#region Data
public string Identifier = String.Empty;
public string Name = String.Empty;
public IPAddress Address = IPAddress.None;
public int Port = 7777;
#endregion
#region IXmlSerializable Implementation
public XmlSchema GetSchema() { return (null); }
public void ReadXml(XmlReader reader)
{
// Attributes
Identifier = reader[XML_IDENTIFIER];
if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
}
public void WriteXml(XmlWriter writer)
{
// Attributes
writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
}
private const string XML_IDENTIFIER = "Id";
private const string XML_NETWORK_ADDR = "Address";
private const string XML_NETWORK_PORT = "Port";
#endregion
}
XmlSerializer を「拡張」する洗練された方法を実装するエレガントな方法を示す興味深い記事があります。
記事には次のように書かれています。
IXmlSerializable は公式ドキュメントでカバーされていますが、ドキュメントには、一般的な使用を意図したものではないと記載されており、それ以上の情報は提供されていません。これは、開発チームが将来的にこの拡張フックを変更、無効化、または完全に削除する権利を留保したかったことを示しています。ただし、この不確実性を受け入れ、将来起こり得る変化に対処する意思がある限り、それを利用できない理由はありません。
IXmlSerializable
このため、複雑すぎる実装を避けるために、独自のクラスを実装することをお勧めします。
XmlSerializer
...リフレクションを使用してカスタム クラスを実装するのは簡単です。