【问题标题】:How to Serialize List<T>?如何序列化列表<T>?
【发布时间】:2011-06-27 17:08:18
【问题描述】:

我有 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 以及 Enum...

什么是序列化此 XML 的好方法,因为我需要将 Object 转换为 XML 和 XML 转换为 Object 的功能......

有什么好的选择可以做到这一点? 谢谢

【问题讨论】:

    标签: c# xml list serialization


    【解决方案1】:

    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();
    

    【讨论】:

    • 看起来很酷,但这是一个 C# 问题而不是 Java。我在您提供的链接中没有看到 .Net 版本,我错过了什么吗?
    【解决方案2】:

    你可以使用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; } 
    }
    

    编辑:

    Enum 属性默认被序列化,属性名称包含 XML 元素,其枚举值作为 XML 值,即如果您的示例中的属性 NotSystem 具有值 C,它将被序列化为

    <NotSystem>C</NotSystem>
    

    当然,您始终可以通过进行适当的注释来更改属性的序列化方式,即使用[XmlAttribute] 将其序列化为属性,或使用[XmlElement("Foobar")] 将其序列化为使用Foobar 作为元素名称。 MSDN 上提供了更广泛的文档,请查看上面的链接。

    【讨论】:

    • 这不是 C#,它不存在接受“Enum eventType e;”的语法
    • @AS-CII 修复了这个问题,我从 OP 的问题中复制了它,没有仔细检查
    • 抱歉我打错了枚举语法应该是 NSystem NotSystem { get;放;其中 NSystem 是枚举类型和公共枚举 NSystem { A = 0, B = 1, C = 2 } 如何在 C# 中序列化/反序列化枚举类型属性
    【解决方案3】:

    你可以用这个

     [XmlArray("array_name")]
     [XmlArrayItem("Item_in_array")]
     public List<T> _List; 
    

    【讨论】:

      【解决方案4】:

      您需要使用 XML 作为表示吗?您可能还想考虑二进制表示,它们通常更快、更紧凑。您拥有内置的BinaryFormatter,或者更好的是您可以使用速度极快且超级紧凑的protocol buffers。 如果您需要 XML,您可能需要考虑是否要支持与其他语言和技术甚至平台的某种互操作性。如果只是 C# 到 c#,则用于 Xml 的 XmlSerializer 或 BinaryFormatter 都可以。如果你打算与 Javascript 交互,你可以考虑使用 JSON(你可以试试JSON.NET. 此外,如果您想支持 Windows Phone 或其他更受限制的设备,使用可在任何地方工作的 XmlSerializer 可能会更容易。

      最后,您可能更喜欢只拥有一个通用基础架构并支持许多序列化机制和传输。微软在WCF 中提供了一个很棒的(虽然有点慢)解决方案。或许,如果您更多地说明您的系统要求,建议实施会更容易。好消息是您有很多选择。

      【讨论】:

        【解决方案5】:

        正如 cloudraven 所建议的,您可以使用二进制表示。在寻找解决方案时,我发现了this 链接。 基本上,您将 A 类标记为 [Serializable],B 和 C 类也是如此。然后你可以使用these ones等函数进行序列化和反序列化

        【讨论】:

          【解决方案6】:
              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);
                  }
              }
          

          【讨论】:

            【解决方案7】:

            最简单的方法:对任何对象(图像以及许多其他数据!)进行BINARY序列化,并捕获IO错误。

            对于我们需要序列化的类,我们需要添加[Serializable]

            [Serializable]//this like
            public class SomeItem
            {}
            

            序列化包装器:

            public static class Serializator
            {
                private static BinaryFormatter _bin = new BinaryFormatter();
            
                public static void Serialize(string pathOrFileName, object objToSerialise)
                {
                    using (Stream stream = File.Open(pathOrFileName, FileMode.Create))
                    {
                        try 
                        {
                            _bin.Serialize(stream, objToSerialise);
                        }
                        catch (SerializationException e) 
                        {
                            Console.WriteLine("Failed to serialize. Reason: " + e.Message);
                            throw;
                        }
                    }
                }
            
                public static T Deserialize<T>(string pathOrFileName) 
                {
                    T items;
            
                    using (Stream stream = File.Open(pathOrFileName, FileMode.Open))
                    {
                        try 
                        {
                            items = (T) _bin.Deserialize(stream);
                        }
                        catch (SerializationException e) 
                        {
                            Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
                            throw;
                        }
                    }
            
                    return items;
                }
            }
            

            以及解决方案的使用:

            List<SomeItem> itemsCollected; //list with some data
            
            Serializator.Serialize("data.dat", itemsCollected); // trying to serialise
            
            
            var a = Serializator.Deserialize<%dataType%>("%dataPath%");
            
            var a = Serializator.Deserialize<List<SomeItem>>("data.dat");
            // trying to DeSerialize; 
            // And important thing that you need to write here 
            // correct data format instead of List<SomeItem>
            

            如果发生错误,错误将被写入控制台。

            【讨论】:

            • 虽然答案没有提到你仍然需要将 [Serializable] 属性添加到你想要序列化的对象的类中。
            • 适用于列表 ?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-10-02
            • 1970-01-01
            • 2012-01-08
            • 2018-08-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多