it-swarm-tr.com

.NET'te serileştirilebilir bir genel Anahtar/Değer çifti sınıfı var mı?

Bir web hizmetine ekleyebileceğim bir anahtar/değer çifti nesnesi arıyorum.

.NET'in System.Collections.Generic.KeyValuePair<> sınıfını kullanmayı denedim, ancak bir web hizmetinde doğru şekilde serileştirilmedi. Bir web hizmetinde, Anahtar ve Değer özellikleri serileştirilmez, bu sorunu çözmenin bir yolunu bilen olmadığı sürece, bu sınıfı işe yaramaz hale getirir.

Bu durum için kullanılabilecek başka bir genel sınıf var mı?

.NET'i System.Web.UI.Pair class kullanırdım, ancak türleri için Object kullanıyor. Yalnızca tür güvenliği için bir Genel sınıfı kullanmak iyi olurdu.

74
Dan Herbert

Sadece bir yapı/sınıf tanımlayın.

[Serializable]
public struct KeyValuePair<K,V>
{
  public K Key {get;set;}
  public V Value {get;set;}
}
90
leppie

Dictionary<>'nin kendisinin XML serileştirilemediğini sanmıyorum, bir web hizmeti aracılığıyla bir sözlük nesnesi göndermem gerektiğinde, Dictionary<> nesnesini kendim sararken ve IXMLSerializable için destek ekleyerek sona erdi.

/// <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
}
22
Compile This

KeyValuePairs'in bu noktada seri hale getirilmesinin nedenini bulacaksınız MSDN Blog Post

Struct cevabı en basit çözüm, ancak tek çözüm değil. "Daha iyi" bir çözüm, Seri hale getirilebilen bir Özel KeyValurPair sınıfı yazmaktır.

17
user56931
 [Serializable]
 public class SerializableKeyValuePair<TKey, TValue>
    {

        public SerializableKeyValuePair()
        {
        }

        public SerializableKeyValuePair(TKey key, TValue value)
        {
            Key = key;
            Value = value;
        }

        public TKey Key { get; set; }
        public TValue Value { get; set; }

    }
5
GregoryBrad

4.0 Çerçevede, seri hale getirilebilir ve eşitlenebilir Tuple sınıf ailesinin eklenmesi de vardır. Tuple.Create(a, b) veya new Tuple<T1, T2>(a, b) kullanabilirsiniz.

1
Peter Oehlert

Anahtar Değer Çiftini işleyebildiğinden, DataContractSerializer'ı kullanın.

    public static string GetXMLStringFromDataContract(object contractEntity)
    {
        using (System.IO.MemoryStream writer = new System.IO.MemoryStream())
        {
            var dataContractSerializer = new DataContractSerializer(contractEntity.GetType());
            dataContractSerializer.WriteObject(writer, contractEntity);
            writer.Position = 0;
            var streamReader = new System.IO.StreamReader(writer);
            return streamReader.ReadToEnd();
        }
    }
0
Hasse

KeyedCollection, doğrudan bir saçmalık olmadan xml'e seri hale getirilebilen bir sözlük türüdür. Tek sorun, değerlere aşağıdakilere erişmeniz gerektiğidir: coll ["key"]. Değer;

0
Will

DataTablename__, JSON'a seri hale getirilecek (yalnızca) sarma verisi için en sevdiğim koleksiyondur, çünkü fazladan struct& Tuple<>[] yerine seri hale getirilebilir bir değiştirme işlemi gerektirmeden genişletmek kolaydır.

Belki de en temiz yol değil, ama yeni bir structbildirmek yerine doğrudan sınıflara dahil etmeyi ve kullanmayı (seri hale getirilecek) kullanmayı tercih ediyorum.

class AnyClassToBeSerialized
{
    public DataTable KeyValuePairs { get; }

    public AnyClassToBeSerialized
    {
        KeyValuePairs = new DataTable();
        KeyValuePairs.Columns.Add("Key", typeof(string));
        KeyValuePairs.Columns.Add("Value", typeof(string));
    }

    public void AddEntry(string key, string value)
    {
        DataRow row = KeyValuePairs.NewRow();
        row["Key"] = key; // "Key" & "Value" used only for example
        row["Value"] = value;
        KeyValuePairs.Rows.Add(row);
    }
}
0
Teodor Tite

XmlSerializer, Sözlüklerle çalışmıyor. Oh, ve KeyValuePairs ile de sorunları var

http://www.codeproject.com/Tips/314447/XmlSerializer-doesnt-work-with-Dictionaries-Oh- ve

0
Akodo_Shado