C# - десериализация списка
Я могу сериализовать список просто:
List<String> fieldsToNotCopy =new List<String> {"Iteration Path","Iteration ID"};
fieldsToNotCopy.SerializeObject("FieldsToNotMove.xml");
Теперь мне нужен такой метод:
List<String> loadedList = new List<String();
loadedList.DeserializeObject("FieldsToNotMove.xml");
есть ли такой метод? Или мне нужно будет создать XML-считыватель и загрузить его таким образом?
EDIT: оказывается, нет встроенного SerialzeObject. Я сделал один раньше в моем проекте и забыл о нем. Когда я нашел его, я думал, что он был встроен. Если вам интересно, это SerializeObject, который я сделал:
// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
TextWriter textWriter = new StreamWriter(filename);
xmlSerializer.Serialize(textWriter, toSerialize);
textWriter.Close();
}
3 ответов
нет такого встроенного метода, как SerializeObject, но его не очень сложно закодировать.
public void SerializeObject(this List<string> list, string fileName) {
var serializer = new XmlSerializer(typeof(List<string>));
using ( var stream = File.OpenWrite(fileName)) {
serializer.Serialize(stream, list);
}
}
И Десериализовать
public void Deserialize(this List<string> list, string fileName) {
var serializer = new XmlSerializer(typeof(List<string>));
using ( var stream = File.OpenRead(fileName) ){
var other = (List<string>)(serializer.Deserialize(stream));
list.Clear();
list.AddRange(other);
}
}
Это мои методы расширения serialize/deserialize, которые работают довольно хорошо
public static class SerializationExtensions
{
public static XElement Serialize(this object source)
{
try
{
var serializer = XmlSerializerFactory.GetSerializerFor(source.GetType());
var xdoc = new XDocument();
using (var writer = xdoc.CreateWriter())
{
serializer.Serialize(writer, source, new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") }));
}
return (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing");
}
catch (Exception x)
{
return new XElement("Error", x.ToString());
}
}
public static T Deserialize<T>(this XElement source) where T : class
{
try
{
var serializer = XmlSerializerFactory.GetSerializerFor(typeof(T));
return (T)serializer.Deserialize(source.CreateReader());
}
catch //(Exception x)
{
return null;
}
}
}
public static class XmlSerializerFactory
{
private static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
public static XmlSerializer GetSerializerFor(Type typeOfT)
{
if (!serializers.ContainsKey(typeOfT))
{
System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT));
var newSerializer = new XmlSerializer(typeOfT);
serializers.Add(typeOfT, newSerializer);
}
return serializers[typeOfT];
}
}
вам просто нужно определить тип вашего списка и использовать его вместо
public class StringList : List<String> { }
О, и Вам не нужен XmlSerializerFactory, он просто есть, так как создание сериализатора медленно, и если вы используете тот же самый снова и снова, это ускоряет ваше приложение.
//A list that holds my data
private List<Location> locationCollection = new List<Location>();
public bool Load()
{
//For debug purposes
Console.WriteLine("Loading Data");
XmlSerializer serializer = new XmlSerializer(typeof(List<Location>));
FileStream fs = new FileStream("CurrencyData.xml", FileMode.Open);
locationCollection = (List<Location>)serializer.Deserialize(fs);
fs.Close();
Console.WriteLine("Data Loaded");
return true;
}
Это позволяет мне десериализовать все мои данные обратно в список, но я бы посоветовал поместить его в блок try-catch для безопасности. На самом деле, просто глядя на это сейчас, я собираюсь переписать это в блоке "using".
надеюсь, это поможет.
EDIT:
извинения, просто заметил, что вы пытаетесь сделать это по-другому, но я все равно оставлю свой ответ там.