.NET中是否有可序列化的通用键/值对类?
时间:2020-03-05 18:58:53 来源:igfitidea点击:
我正在寻找可以包含在Web服务中的键/值对对象。
我尝试使用.NET的System.Collections.Generic.KeyValuePair <>
类,但是它无法在Web服务中正确序列化。在Web服务中,键和值属性不会被序列化,从而使该类无用,除非有人知道解决该问题的方法。
还有其他通用类可以用于这种情况吗?
我会使用.NET的System.Web.UI.Pair
类,但是它使用Object作为其类型。如果仅出于类型安全性考虑,使用Generic类会很好。
解决方案
回答
只需定义一个结构/类。
[Serializable] public struct KeyValuePair<K,V> { public K Key {get;set;} public V Value {get;set;} }
回答
我不认为是因为Dictionary <>本身不是XML可序列化的,当我需要通过Web服务发送字典对象时,我最终自己包装了Dictionary <>对象并添加了对的支持IXMLSerializable
。
/// <summary> /// Represents an XML serializable collection of keys and values. /// </summary> /// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam> /// <typeparam name="TValue">The type of the values in the dictionary.</typeparam> [XmlRoot("dictionary")] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable { #region Constants /// <summary> /// The default XML tag name for an item. /// </summary> private const string DEFAULT_ITEM_TAG = "Item"; /// <summary> /// The default XML tag name for a key. /// </summary> private const string DEFAULT_KEY_TAG = "Key"; /// <summary> /// The default XML tag name for a value. /// </summary> private const string DEFAULT_VALUE_TAG = "Value"; #endregion #region Protected Properties /// <summary> /// Gets the XML tag name for an item. /// </summary> protected virtual string ItemTagName { get { return DEFAULT_ITEM_TAG; } } /// <summary> /// Gets the XML tag name for a key. /// </summary> protected virtual string KeyTagName { get { return DEFAULT_KEY_TAG; } } /// <summary> /// Gets the XML tag name for a value. /// </summary> protected virtual string ValueTagName { get { return DEFAULT_VALUE_TAG; } } #endregion #region Public Methods /// <summary> /// Gets the XML schema for the XML serialization. /// </summary> /// <returns>An XML schema for the serialized object.</returns> public XmlSchema GetSchema() { return null; } /// <summary> /// Deserializes the object from XML. /// </summary> /// <param name="reader">The XML representation of the object.</param> public void ReadXml(XmlReader reader) { XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); bool wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) { return; } while (reader.NodeType != XmlNodeType.EndElement) { reader.ReadStartElement(ItemTagName); reader.ReadStartElement(KeyTagName); TKey key = (TKey)keySerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadStartElement(ValueTagName); TValue value = (TValue)valueSerializer.Deserialize(reader); reader.ReadEndElement(); this.Add(key, value); reader.ReadEndElement(); reader.MoveToContent(); } reader.ReadEndElement(); } /// <summary> /// Serializes this instance to XML. /// </summary> /// <param name="writer">The writer to serialize to.</param> public void WriteXml(XmlWriter writer) { XmlSerializer keySerializer = new XmlSerializer(typeof(TKey)); XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); foreach (TKey key in this.Keys) { writer.WriteStartElement(ItemTagName); writer.WriteStartElement(KeyTagName); keySerializer.Serialize(writer, key); writer.WriteEndElement(); writer.WriteStartElement(ValueTagName); TValue value = this[key]; valueSerializer.Serialize(writer, value); writer.WriteEndElement(); writer.WriteEndElement(); } } #endregion }
回答
KeyedCollection是一种字典类型,可以直接序列化为xml,而无需任何废话。唯一的问题是,我们必须通过以下方式访问值:coll [" key"]。Value;
回答
我们将在此MSDN博客文章中找到无法对KeyValuePairs进行序列化的原因。
Struct答案是最简单的解决方案,但不是唯一的解决方案。一个"更好"的解决方案是编写一个可序列化的Custom KeyValurPair类。