开发者

Why can't a dictionary object be XmlSerialized in C#?

开发者 https://www.devze.com 2022-12-08 09:37 出处:网络
It seems that serialization is very straightforward. Assuming that both the key and value are serializable, what could be simpler than representing key-value pairs in XML?!

It seems that serialization is very straightforward. Assuming that both the key and value are serializable, what could be simpler than representing key-value pairs in XML?!

To a开发者_JAVA百科ll the commenters: First of all, I appreciate your answers, But- I am less interested in workoraunds (There is indeed plenty of SerializableDictionary implementations on the web for picking) and more as to the reason for this design decision.


This guy created an xml serializable dictionary.


"Why" part:

Unfortunately there's no way to make XmlSerializer function with IDictionary-derived objects since the infrastructure explicitly checks for IDictionary at run time and disables serialization. One way around this is to write a new class that wraps an IDictionary object and copies the values into an array of serializable objects. The XmlSerializer framework also has a hidden hook for writing custom serialization code. To take advantage of this hook you can implement an interface called IXmlSerializable for the object you want to serialize/deserialize.

When you instantiate an XmlSerializer object, the constructor usually generates a temporary assembly containing XmlReader and XmlWriter code for moving between object instances and XML documents. Before doing this, however, it first checks to see if the supplied type derives from IXmlSerializable and if so, it generates code to call into the IXmlSerializable members instead. In other words, if you implement IXmlSerializable, you completely bypass the automatic serialization process and have the opportunity to provide your own.

You can read entire article here: XML Files: Advanced Type Mappings


Ok, you want to know why?

The XML Serializer isn't just about serializing and deserializing. It's also about serializing/deserializing XML that validates against the XML Schema that is also produced by XML Serialization.

How would you define a dictionary in XML Schema? When you do, will you maintain the semantics of unique key? If you do, will any caller be able to look at that schema definition and determine that it really means a dictionary?


I've just read Collection Types in Data Contracts and learned more about data contracts and collections than I had previously thought existed. I recommend that anyone interested in the subject read that section, the sections it references, and the related sections.

Among other things, you'll learn how the DataContractSerializer gets solves the problem of XML Schema having no way to describe a dictionary - it adds a WCF-specific annotation to the XML schema. Only code that understands that annotation will know that the schema is describing a dictionary.


Presuming that your question is (too) how to serialize a Dictionary in an xml format, the partial answer is: use DataContractSerializer:

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;//you need to set a reference to System.Runtime.Serialization.dll!

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var dictionary = new Dictionary<int, string>();
            dictionary.Add(1,"John");
            dictionary.Add(2,"Jane");

            var serializer = new DataContractSerializer(typeof(Dictionary<int, string>));
            using (var stream = new FileStream("dictionary.xml", FileMode.Create, FileAccess.Write))
            {
                serializer.WriteObject(stream,dictionary);
            }

            var xml = File.ReadAllText("dictionary.xml");

            Console.WriteLine("dictionary was stored as: {0}",xml);
            Console.ReadLine();
        }
    }
}


The why is simple: XmlSerializer doesn't support private members, deep serialization or fields of types without a default constructor. In short, it's pretty much useless in most scenarios.

Here's a solution that may work as an alternate option: http://sourceforge.net/projects/nxmlserializer/


Use DataContract Serialization from WCF. Here is a link.

It is different from ISerializable in that it is an opt-in where as ISerializable is opt-out.

Here is a link that talks of collections with DataContract serialization.

0

精彩评论

暂无评论...
验证码 换一张
取 消