Как я должен десериализовать эти строковые данные? - PullRequest
0 голосов
/ 02 февраля 2009

Мое приложение получает строки, которые представляют объекты. Я должен проанализировать строки, чтобы получить значения свойств для объекта, который я создаю. Каждый объект должен знать особенности количества атрибутов, значения каждого атрибута и т. Д. Однако я хочу, чтобы каждый класс не знал, как анализировать строку. Я бы предпочел передать каждому отдельному объекту более подходящую структуру данных (например, набор данных или XML) ... что-то более простое для заполнения его свойств.

Есть ли что-то встроенное в .NET Framework, подходящее для такого типа вещей? Или я должен создать свой собственный контейнерный объект?

ADD:

Не думаю, что сначала я объяснил свой вопрос достаточно хорошо. Вот пример для пояснения.

Допустим, моей программе всегда передается строка символов, представляющая таблицу данных в синтаксисе Wiki. Что-то вроде:

  {||Client:||ABC|-|Contact:||Joe Smith|-|Current revision:||1.0||}

Я не хочу, чтобы каждый из моих конкретных объектов вики-таблиц (например, ClientContactTable, CustomerOrderTable и т. Д.) Знал, как анализировать | и и }. Поэтому я хотел бы написать 1 кусок кода, который анализирует строку в некотором объекте «среднего» уровня, который я могу передать конструктору каждого конкретного объекта таблицы Wiki.

Мой вопрос: каким должен быть этот объект среднего уровня?

Ответы [ 5 ]

3 голосов
/ 02 февраля 2009

Возможно, я неправильно понял ваш вопрос, но я думаю, что стандартная сериализация .NET соответствует вашим потребностям:

var ms = new MemoryStream();
var formatter = new BinaryFormatter();
formatter.Serialize(ms, myObject);

// Deserialization:
var deserialized = (MyClass)formatter.Deserialize(stream);
3 голосов
/ 02 февраля 2009
1 голос
/ 02 февраля 2009

Один из традиционных способов сделать это - через классы System.Xml.Serialization. Это позволяет вам сериализовать ваши объекты на диск и впоследствии десериализовать их. Это имеет некоторые ограничения: типы должны быть открытыми, иметь открытый конструктор без параметров и иметь атрибут XmlSerializer.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;


namespace ConsoleApplication1
{
    [Serializable]
    public class Cat
    {
        DateTime _dateOfBirth;
        string _name;

        public DateTime DateOfBirth
        {
            get { return _dateOfBirth; }
            set { _dateOfBirth = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public Cat() : this(DateTime.Now, "(Cat with no name)") { }

        public Cat(DateTime dateOfBirth, string name)
        {
            this.DateOfBirth = dateOfBirth;
            this.Name = name;
        }

        public override string ToString()
        {
            return string.Format("Name: {0}, DateOfBirth: {1}", Name, DateOfBirth);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Cat originalCat = new Cat(DateTime.Now, "Fluffy");
            XmlSerializer serializer = new XmlSerializer(typeof(Cat));

            MemoryStream memStream = new MemoryStream(); // can be file stream
            serializer.Serialize(memStream, originalCat);

            memStream.Position = 0; // this is just here to make this code sample work, usually you
                                    // you don't need to set your streams position manually

            Cat deserializedCat = (Cat)serializer.Deserialize(memStream);

            Console.WriteLine("originalCat.ToString(): {0}", originalCat.ToString());
            Console.WriteLine("deserializedCat.ToString(): {0}", deserializedCat.ToString());

            Console.ReadKey(true);
        }
    }
}

В общем, вы должны быть очень осторожными с такого рода сериализацией. Странность возникает, когда вы пытаетесь сериализовать / десериализовать объекты между различными версиями одной и той же сборки.

Изменить, чтобы добавить: Приведенный выше код будет сериализовать ваш объект в XML. Вы можете увидеть представление XML, заменив вашу MemoryString вместо StringWriter (вызовите метод stringWriterInstance.ToString () для прямого получения строки XML). Другие предложили использовать BinaryFormatter, который делает более или менее то же самое, но вывод является двоичным, а не текстовым.

Оба подхода являются допустимыми способами сериализации данных, все зависит от того, нравится ли вам больше работать с XML или двоичными данными.

0 голосов
/ 02 февраля 2009

Если вам нужно сохранить ваш объект (ы), вы должны использовать XmlSerializer (s). Это будет де-сериализовать ваши объекты в XML и проанализировать их для вас.

public List<_type> LoadDataFromResource<_type>(string file)
{
   List<_type> data = new List<_type>();
   FileStream str = File.OpenRead(file);
   if (str == null) return null;
   XmlSerializer sr = new XmlSerializer(data.GetType());
   if (sr == null) return null;
   data = sr.Deserialize(str) as List<_type>;
   return data;
}

public bool SaveData<_type>(string file, List<_type> data)
{
StreamWriter writer = File.CreateText(file);
if (writer == null) return false;
XmlSerializer sr = new XmlSerializer(data.GetType());
if (sr == null) return false;
sr.Serialize(writer, data);
return true;
}
0 голосов
/ 02 февраля 2009

вам нужно проанализировать строковые данные и преобразовать их в объект или xml - я бы посоветовал вам использовать string.split для создания коллекции (массива), а затем использовать linq для создания необходимой структуры данных и передачи на завод который возвращает вам правильный объект на основе параметра, который вы передаете в facotry вместе со структурой данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...