CodeGym /Courses /C# SELF /Serialization of simple collections:

Serialization of simple collections: List<T>, T[]

C# SELF
Level 46 , Lesson 0
Available

1. Introduction

We've already worked with collections. You can't do without them in programming or in life. Imagine you're making a to-do list for the day: buy groceries, call the doctor, pick up an order. You probably won't create a separate notebook for each task. It's way simpler and more logical to put all tasks into one list.

Same in programming: when the number of objects grows — users, orders, messages — we don't create a separate variable for each. Instead we use collections: lists, dictionaries, sets. That lets you conveniently store, iterate and process whole groups of data at once.

Real-life scenarios:

  • Storing and exchanging data between applications: your collection of books might migrate from one program to another.
  • Caching datasets to disk.
  • Sending data over the network (frontend ↔ backend).
  • Import/export of information (for example, you decided to add JSON export for your books!).

On an interview: “How would you serialize and save a list of orders?” — it's great if you mention not only single-object serialization but also collection serialization!

2. How collections work during serialization

JSON and collections: a short love story

When you serialize a regular object, it becomes a JSON object like { "field": value }. But when you serialize a list or array, you get a JSON array [ ... ].

Visually:

C# JSON
List<int> { 1, 2, 3 }
[1, 2, 3]
Book[]
[{"Title":"A","Author":"B"}, ...]
List<Book>
[{"Title":"A"}, {"Title":"B"}]

The main magic: Call JsonSerializer.Serialize() on a collection — and it automatically turns it into an array! The reverse with Deserialize<List<T>>() — and the magic works again.

Mapping between C# collections and JSON arrays

C# collection type Example JSON
Book[]
new Book[] { ... }
[ { ... }, { ... } ]
List<Book>
new List<Book> { ... }
[ { ... }, { ... } ]
int[]
new int[] { 1, 2, 3 }
[1, 2, 3]
List<string>
new List<string> { "a", "b" }
["a", "b"]
List<List<Book>>
new List<List<Book>> { ... }
[ [ { ... } ], [ { ... } ] ]

3. Example: serializing and deserializing an array of books

Let's start with a minimal example. Take our Book class that we used in previous lectures:

public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
}

Now create an array of books, serialize it, save it to a file and load it back.

using System;
using System.IO;
using System.Text.Json;

namespace LibraryApp
{
    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
    }

    class Program
    {
        static void Main()
        {
            // Create an array of books
            Book[] books = new Book[]
            {
                new Book { Title = "Tri tovarishcha", Author = "Erikh Mariya Remark" },
                new Book { Title = "Master i Margarita", Author = "Mikhail Bulgakov" },
                new Book { Title = "1984", Author = "Dzhordzh Oruell" }
            };

            // Serialize the array of books to a string
            var options = new JsonSerializerOptions { WriteIndented = true };	
            string json = JsonSerializer.Serialize(books, options);
            Console.WriteLine("JSON of the books array:\n" + json);

            // Write to a file (synchronously)
            File.WriteAllText("books.json", json);

            // Read from the file (synchronously)
            string jsonFromFile = File.ReadAllText("books.json");

            // Deserialize back to an array
            Book[]? booksFromFile = JsonSerializer.Deserialize<Book[]>(jsonFromFile);

            // Print the result to the console
            Console.WriteLine("\nDeserialized books:");
            if (booksFromFile != null)
            {
                foreach (var book in booksFromFile)
                {
                    Console.WriteLine($"- {book.Title} (author: {book.Author})");
                }
            }
        }
    }
}

What's happening here?

  • We create a Book[], fill it with three books.
  • Using JsonSerializer.Serialize we turn the array into a pretty JSON string (the WriteIndented option makes the formatting readable).
  • We write it to a file, read it back and deserialize — and now we have the array of books again!
  • We verify that all data was restored correctly.

Check that the file "books.json" appears in the program folder. Open it — you'll see roughly this JSON:

[
  {
    "Title": "Tri tovarishcha",
    "Author": "Erikh Mariya Remark"
  },
  {
    "Title": "Master i Margarita",
    "Author": "Mikhail Bulgakov"
  },
  {
    "Title": "1984",
    "Author": "Dzhordzh Oruell"
  }
]

4. Example: serializing a List<T> collection

Working with List<Book> is no different. The serializer sees the collection and turns it into a JSON array.

List<Book> myBooks = new List<Book>
{
    new Book { Title = "Prestuplenie i nakazanie", Author = "Fyodor Dostoevskiy" },
    new Book { Title = "Voyna i mir", Author = "Lev Tolstoy" }
};

string jsonList = JsonSerializer.Serialize(myBooks, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(jsonList);

// And we deserialize like this:
List<Book>? loadedBooks = JsonSerializer.Deserialize<List<Book>>(jsonList);

// Check that everything came back!
foreach (var book in loadedBooks!)
{
    Console.WriteLine($"{book.Title} ({book.Author})");
}

Can you serialize just a list of integers?

Of course! Serialization works not only for your classes but also for primitive types:

List<int> numbers = new List<int> { 10, 20, 30, 40 };
string jsonNums = JsonSerializer.Serialize(numbers); // result: [10,20,30,40]
List<int>? loadedNums = JsonSerializer.Deserialize<List<int>>(jsonNums);
// loadedNums: List<int> with the same values

5. Diagram and analogies: how the serializer sees collections

To better understand how collection serialization works, look at a simple diagram:

graph TD;
    A[List[Book] in C#] -->|Serialize| B[JSON array as a string]
    B -->|Write| C[File books.json]
    C -->|Read| D[JSON string from file]
    D -->|Deserialize| E[List[Book] in C#]

Briefly describing the process:

  • A collection or array is serialized as a JSON array ([ ... ]).
  • The order of elements is preserved (unless you apply special settings).
  • Each element of the collection is serialized as its own object.

6. Particulars of serializing collections: what to watch out for

1. null and empty collections

If a collection is null, the serializer by default will write null into JSON. Be careful if in your business logic an empty collection and null are not the same!

If a collection is empty (new List<Book>()), the JSON will be [] — an empty array. That's convenient when you want to explicitly show there are no items.

2. Deserialization — order matters

The order of elements in the array is always preserved. So if you serialized three books in a certain order, they'll be restored in the same order.

3. A collection with objects of different types?

System.Text.Json doesn't support polymorphism "out of the box". So if you have, for example, a List<Animal> with dogs and cats (each a derived class), you can't by default restore which exact type each item was. We'll cover polymorphic serialization later, but for regular lists — it's simple.

7. Typical mistakes and common misunderstandings

Mistake #1: You serialize a collection but forget that it may contain objects with private fields

JsonSerializer serializes only public properties (with getters/setters). If your class looks like this:

public class User
{
    public string Login { get; set; }

    private string Password { get; set; }  // Will not be serialized!
}

The password won't get into JSON, and that's good for security. But if you intended to save it — don't forget to make the property public.

Mistake #2: Serializing collections with null elements

If the collection contains null, for example: new List<Book> { null, book2 }, then after serialization the first element will be null. During deserialization — the same! Example JSON:

[null, { "Title": "Voyna i mir", "Author": "Lev Tolstoy" }]

In practice this is rare, but if you serialize a collection that may have "holes" — handle that in your logic.

Mistake #3: Wrong type during deserialization

A common typo: you serialized a list but deserialize into an array (or vice versa). This works if types are compatible (Book[]List<Book>), but sometimes there are nuances — e.g., you try to deserialize an array of strings into a single object instead of a collection.

2
Task
C# SELF, level 46, lesson 0
Locked
Serialization and Deserialization of a List of Strings
Serialization and Deserialization of a List of Strings
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION