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 и загрузить его таким образом?


Править: Повороты там не созданы в 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();
}
10
задан Vaccano 4 February 2010 в 18:19
поделиться

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);
  }
}
19
ответ дан 3 December 2019 в 16:52
поделиться

Это мои методы расширения сериализации/десериализации, которые хорошо работают

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, он просто есть, так как создание сериалайзера медленно, и если вы используете один и тот же тип снова и снова, то это ускоряет работу вашего приложения.

4
ответ дан 3 December 2019 в 16:52
поделиться

Дополнительный метод не допускает, чтобы подэлементы были нулевыми. Конструктор предмета можно сделать таким образом, чтобы он по умолчанию устанавливал пустой список, а затем не допускал значение NULL в установщике подэлемента.

Это, конечно, предполагает, что у вас есть доступ для изменения предмета.

Нулевой оператор объединения - это то, что вы ищете, как указал Хантер Дэйли

-121--3767177-

Заключите ответный вызов в инструкцию using, чтобы убедиться, что соединение всегда закрыто:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url)
// ...
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
  // ...
}

Также заключите любой GetResponseStream () в инструкцию using.

-121--2561306-

Я не уверен, поможет ли это вам, но у меня есть купол, что я считаю похожим на вас.

//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 для безопасности. На самом деле просто смотреть на это сейчас заставит меня переписать это в блок «использования» тоже.

Надеюсь, это поможет.

ПРАВКА:

Извинения, просто заметили, что вы пытаетесь сделать это другим путем, но я оставлю свой ответ там в любом случае.

1
ответ дан 3 December 2019 в 16:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: