Как сериализовать список?
У меня есть класс 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, а также перечисление...
каков хороший подход к сериализации этого XML, потому что мне нужна функциональность преобразования объекта в XML и XML в объект ...
какие есть хорошие варианты для этого? Спасибо
7 ответов
можно использовать 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>
конечно, вы всегда можете изменить способ сериализации свойства, выполнив правильную аннотацию, i.e использование [XmlAttribute]
таким образом, он сериализуется как атрибут или [XmlElement("Foobar")]
таким образом, он сериализуется с помощью Foobar
в качестве имени элемента. Более подробная документация доступна на MSDN, проверьте ссылку выше.
вы можете использовать этот
[XmlArray("array_name")]
[XmlArrayItem("Item_in_array")]
public List<T> _List;
простой способ сделать бинарные сериализация любой объект с ловлей ошибок ввода-вывода.
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;
}
}
вам нужно использовать XML в качестве представления? Вы можете также рассмотреть двоичные представления, которые обычно быстрее и компактнее. У вас есть BinaryFormatter это встроено, или даже лучше, вы можете использовать протокол буферы это пылающий быстро и супер компактный. Если вам нужен XML, вы можете подумать, хотите ли вы поддерживать какие-то взаимодействия с другими языками и технологиями или даже платформ. Если это только C# для c# оба XmlSerializer для Xml или BinaryFormatter в порядке. Если вы собираетесь взаимодействовать с Javascript, вы можете использовать JSON (вы можете попробовать JSON.NET. Кроме того, если вы хотите поддерживать Windows Phone или другие более ограниченные устройства, может быть проще использовать XmlSerializer, который работает в любом месте.
наконец, вы можете предпочесть просто иметь общую инфраструктуру и поддерживать многие механизмы сериализации и транспорты. Microsoft предлагает замечательное (хотя и немного медленное) решение в WCF. Возможно, если вы расскажете больше о требованиях вашей системы, будет легче предложить реализацию. Хорошо, что у вас есть много вариантов.
Как предложил cloudraven, вы можете использовать двоичные представления. В поисках решений я наткнулся этой ссылка. В принципе, вы отмечаете свой класс A как [сериализуемый], и то же самое касается ваших классов B и C. Тогда вы можете использовать такие функции, как эти для сериализации и десериализации
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);
}
}
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();