【问题标题】:How to Serialise a List of instance nested within a class?如何序列化嵌套在类中的实例列表?
【发布时间】:2019-05-11 19:42:25
【问题描述】:

我正在尝试将一个类保存到带有序列化的文件中,它适用于所有属性,但无法序列化嵌套类。

假设我的类代表一个具有名称、描述、...的任务,它可以由由任务列表表示的子任务组成

我尝试在我的列表之前写 [Serializable],就像在此处解释:Serialize Nested Classes in c#?

但我收到此错误:“属性 'Serializable' 在此声明类型上无效。它仅在声明上有效。”

[Serializable()]
public class t_Task
{
   private string nom;
   private string description;
   [Serializable]
   List<t_Task> subTask;
}

如何让列表中的所有类也序列化?

编辑:我正在使用此处找到的方法进行序列化:http://blog.danskingdom.com/saving-and-loading-a-c-objects-data-to-an-xml-json-or-binary-file/

public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
    using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
    {
        var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        binaryFormatter.Serialize(stream, objectToWrite);
    }
}

然后我用一个接近这个的方法来调用它

public void Save()
        {
            GesionBinaryFileIO.WriteToBinaryFile<t_Task>(PathToFile, this);
        }

【问题讨论】:

    标签: c# list class serialization


    【解决方案1】:

    [Serializeable] 不允许在字段/属性上,只需要放在类上。您的类应该是可序列化的,如下所示:

    [Serializable()]
    public class t_Task
    {
       private string nom;
       private string description;
       List<t_Task> subTask; // Removed the [Serializeable] attribute
    }
    

    请务必注意,您的 List&lt;t_Task&gt; 不是嵌套类(它只是一个常规类字段),因此您引用的链接实际上与您的问题无关。

    [Serializable] 是一种比较古老的序列化标记方法。我会在SerializeableAttribute 上引用Microsoft documentation,看看你的代码是如何工作的。

    这是基于我链接的 Microsoft 文章的示例:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace ConsoleOne
    {
        [Serializable()]
        public class t_Task
        {
            private string nom = "test"; // Added for test data.
            private string description = "desc"; // Added for test data
            List<t_Task> subTask = new List<t_Task>();
    
            public void AddTask()
            {
                this.subTask.Add(new t_Task());
            }
    
            public override string ToString()
                => $"{nom}-{description}-{subTask?.Count}";
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                var task = new t_Task()
                {
    
                };
    
                task.AddTask();
                task.AddTask();
    
                // Opens a file and serializes the object into it in binary format.
                Stream stream = File.Open("data.xml", FileMode.Create);
    
                BinaryFormatter formatter = new BinaryFormatter();
    
                formatter.Serialize(stream, task);
                stream.Close();
    
                //Empties obj.
                task = null;
    
                //Opens file "data.xml" and deserializes the object from it.
                stream = File.Open("data.xml", FileMode.Open);
                formatter = new BinaryFormatter();
    
                //formatter = new BinaryFormatter();
    
                task = (t_Task)formatter.Deserialize(stream);
                stream.Close();
    
                Console.WriteLine($"{task}");
                Console.ReadLine();
            }
        }
    }
    

    注意:.NET 中还有许多其他更现代的序列化途径。这些内容可能也值得一读。但是,如果您只对简单的二进制格式感兴趣,那么以上信息就足够了。

    【讨论】:

    • 我已经更新了我的帖子,以提供有关我如何序列化课程的更多信息。使用 XML 重要吗?我尝试将它们保存为二进制文件
    • @Nux 我认为没有必要使用 XML。如果您查看我的示例,我实际上也使用了BinaryFormatter。我的大部分答案都是解释。我会更新它以阐明解决您的问题的重要部分。
    • 感谢您的回复,感谢您的回复,我认为我的问题在于加载部分而不是保存部分。如果我不解决它,我将创建另一个帖子
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多