我该如何反序列化这个字符串数据?

时间:2009-02-02 17:09:48

标签: .net parsing serialization data-structures

我的应用程序接收表示对象的字符串。我必须解析字符串以获取我正在创建的对象的属性值。每个对象都必须知道有多少属性的具体信息,每个属性的含义等等。但是,我想避免让每个类知道如何解析字符串。我宁愿将每个单独的对象传递给更合适的数据结构(如数据集或XML)......更容易填充其属性。

.NET框架内置了适合此类事物的内容吗?或者我应该创建自己的容器对象吗?

添加

我认为我最初没有充分解释我的问题。这是一个澄清的例子。

假设我的程序总是传递一个字符串,表示Wiki语法中的数据表。类似的东西:

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

我不希望每个特定的wiki表对象(例如,ClientContactTable,CustomerOrderTable等)都知道如何解析|和 - 和}。所以我想编写一大块代码,将字符串解析为一些“中间”层对象,我可以将其传递给每个特定Wiki表对象的构造函数。

我的问题是:该中间层对象应该是什么?

5 个答案:

答案 0 :(得分:3)

答案 1 :(得分:3)

我可能错误地理解了您的问题,但我认为标准的.NET序列化适合您的需求:

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

// Deserialization:
var deserialized = (MyClass)formatter.Deserialize(stream);

答案 2 :(得分:1)

一种传统的方法是通过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。您可以通过使用StringWriter替换MemoryString来查看XML表示(调用stringWriterInstance.ToString()方法直接获取XML字符串)。其他人建议使用BinaryFormatter,它或多或少地做同样的事情,但输出是二进制而不是文本。

这两种方法都是序列化数据的有效方法,它只取决于您是否更喜欢处理XML或二进制数据。

答案 3 :(得分:0)

你需要解析字符串数据并将其转换为对象或xml - 我建议你使用string.split创建一个集合(数组)然后使用linq创建你想要的数据结构并传递给工厂根据您传递给facotry的参数以及数据结构返回正确的对象。

答案 4 :(得分:0)

如果您需要存储对象,则应使用XmlSerializer。 这会将您的对象解序/序列化为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;
}