Как сериализовать список <T>? - PullRequest
9 голосов
/ 15 февраля 2011

У меня есть класс A. Класс B и класс C являются частью класса A.

Class A 
{

//Few Properties of Class A

List<typeof(B)> list1 = new List<typeof(B)>()

List<typeof(C)> list2 = new List<typeof(C)>()

Nsystem NotSystem { get; set; } // Enum Property Type

}

public enum Nsystem {
    A = 0,
    B = 1,
    C = 2
}

Я хочу сериализировать класс A и хочу создавать XML с ним; Я также хочу сериализовать list1 и list2, а также Enum ...

Каков хороший подход к сериализации этого XML, потому что мне нужна функциональность преобразования объекта в XML и XML в объект ...

Какие есть хорошие варианты для этого? Спасибо

Ответы [ 7 ]

9 голосов
/ 15 февраля 2011

Вы можете использовать XMLSerializer :

var aSerializer = new XmlSerializer(typeof(A));
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
aSerializer.Serialize(sw, new A()); // pass an instance of A
string xmlResult = sw.GetStringBuilder().ToString();

Чтобы это работало должным образом, вам также понадобятся xml-аннотации для ваших типов, чтобы убедиться, что они сериализуются с правильными именами, т. Е .:

public enum NSystem { A = 0, B = 1, C = 2 }

[Serializable]
[XmlRoot(ElementName = "A")]
Class A 
{
 //Few Properties of Class A
 [XmlArrayItem("ListOfB")]
 List<B> list1;

 [XmlArrayItem("ListOfC")]
 List<C> list2;

 NSystem NotSystem { get; set; } 
}

Edit:

Enum свойства сериализуются по умолчанию с именем свойства как содержащего XML-элемент и его перечислимым значением как XML-значение, т. Е. Если свойство NotSystem в вашем примере имеет значение C, оно будет сериализовано как

<NotSystem>C</NotSystem>

Конечно, вы всегда можете изменить способ сериализации свойства, выполнив правильную аннотацию, то есть, используя [XmlAttribute], чтобы он сериализовался как атрибут, или [XmlElement("Foobar")], чтобы он сериализовался, используя Foobar в качестве имени элемента. Более обширная документация доступна на MSDN, проверьте ссылку выше.

5 голосов
/ 02 июля 2018

Простой способ сделать двоичный сериализация любого объекта с перехватом ошибок ввода-вывода.

List<Cookie> asdf = new List<Cookie>();

//Serialization
Serializer.Save("data.bin", asdf);

//Deserialization
asdf = Serializer.Load<List<Cookie>>("data.bin");

Класс сериализатора:

public static class Serializer
{
    public static void Save(string filePath, object objToSerialize)
    {
        try
        {
            using (Stream stream = File.Open(filePath, FileMode.Create))
            {
                BinaryFormatter bin = new BinaryFormatter();
                bin.Serialize(stream, objToSerialize);
            }
        }
        catch (IOException)
        {
        }
    }

    public static T Load<T>(string filePath) where T : new()
    {
        T rez = new T();

        try
        {
            using (Stream stream = File.Open(filePath, FileMode.Open))
            {
                BinaryFormatter bin = new BinaryFormatter();
                rez = (T) bin.Deserialize(stream);
            }
        }
        catch (IOException)
        {
        }

        return rez;
    }
}
1 голос
/ 19 января 2017
    public IList<Object> Deserialize(string a_fileName)
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(List<Object>));

        TextReader reader = new StreamReader(a_fileName);

        object obj = deserializer.Deserialize(reader);

        reader.Close();

        return (List<Object>)obj;
    }

    public void Serialization(IList<Object> a_stations,string a_fileName)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(List<Object>));

        using (var stream = File.OpenWrite(a_fileName))
        {
            serializer.Serialize(stream, a_stations);
        }
    }
1 голос
/ 23 марта 2013

Вы можете использовать это

 [XmlArray("array_name")]
 [XmlArrayItem("Item_in_array")]
 public List<T> _List; 
0 голосов
/ 13 мая 2016

Как предположил cloudraven, вы можете использовать двоичные представления. При поиске решений я наткнулся на эту ссылку. По сути, вы помечаете свой класс A как [Serializable], и ​​то же самое относится и к вашим классам B и C. Тогда вы можете использовать такие функции, как эти для сериализации и десериализации

0 голосов
/ 23 марта 2013

Вам нужно использовать XML в качестве представления?Вы можете также рассмотреть двоичные представления, которые обычно бывают быстрее и компактнее.У вас есть встроенный BinaryFormatter , или, что еще лучше, вы можете использовать буферы протокола , которые невероятно быстрые и суперкомпактные.Если вам нужен XML, вы можете подумать, хотите ли вы поддерживать какую-то совместимость с другими языками и технологиями или даже платформами.Если это только C # - c #, то все XmlSerializer для Xml или BinaryFormatter вполне подойдут.Если вы собираетесь взаимодействовать с Javascript, вы можете подумать об использовании JSON (вы можете попробовать JSON.NET . Кроме того, если вы хотите поддерживать Windows Phone или другие более ограниченные устройства, это может быть проще в использованииXmlSerializer, который работает где угодно.

Наконец, вы можете предпочесть просто иметь общую инфраструктуру и поддерживать множество механизмов и транспортов сериализации. Microsoft предлагает замечательное (хотя и немного медленное) решение в WCF Возможно, если вы скажете больше о требованиях вашей системы, вам будет проще предложить реализацию. Хорошо, что у вас есть много вариантов.

0 голосов
/ 15 февраля 2011

JAXB - лучшее, что я когда-либо использовал.

http://www.oracle.com/technetwork/articles/javase/index-140168.html

Из XML:

QuestionEntity obj = null;
try {
    JAXBContext ctx = JAXBContext.newInstance(QuestionEntity.class);
    Unmarshaller unmarshaller = ctx.createUnmarshaller();
    obj = (QuestionEntity) unmarshaller.unmarshal(new StreamSource(new StringReader(xml)));
} catch (JAXBException e) {
    e.printStackTrace();
}

В XML:

JAXBContext ctx = JAXBContext.newInstance(TestEntity.class);
Marshaller marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter stringWriter = new StringWriter();
marshaller.marshal(this, stringWriter);
return stringWriter.toString();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...