1. Introdução
A gente já trabalhou com coleções. Sem elas não dá nem na programação, nem na vida. Imagine que você faz uma lista de afazeres: comprar mantimentos, ligar pro médico, pegar um pedido. Difícil seria criar um caderno separado pra cada tarefa. Muito mais simples e lógico anotar tudo numa única lista.
O mesmo vale na programação: quando os objetos aumentam — usuários, pedidos, mensagens — nem sempre criamos uma variável separada pra cada um. Em vez disso usamos coleções: listas, dicionários, sets. Isso facilita armazenar, iterar e processar grupos inteiros de dados.
Cenários do mundo real:
- Armazenamento e troca de dados entre aplicações: sua coleção de livros pode migrar de um programa para outro.
- Cache de conjuntos de dados no disco.
- Transmissão de dados pela rede (frontend ↔ backend).
- Import/export de informação (por exemplo, você decidiu fazer um export dos seus livros em JSON!).
No processo seletivo: “Como você serializaria e salvaria uma lista de pedidos?” — fica legal se você souber falar não só sobre um objeto isolado, mas também sobre serialização de coleções!
2. Como as coleções funcionam durante a serialização
JSON e coleções: uma rápida história de amor
Quando você serializa um objeto normal, ele vira um objeto JSON do tipo { "field": value }. Mas se serializar uma lista ou um array, o resultado é um array JSON [ ... ].
Visualmente:
| C# | JSON |
|---|---|
|
|
|
|
|
|
A mágica principal: Chamamos JsonSerializer.Serialize() para a coleção — e ele automaticamente a transforma em um array! No caminho inverso, Deserialize<List<T>>() — e a mágica acontece de novo.
Correspondência entre coleções C# e arrays JSON
| Tipo de coleção em C# | Exemplo | JSON |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3. Exemplo: serialização e desserialização de um array de livros
Vamos começar com um exemplo mínimo. Pegue nossa classe Book, que já usamos em aulas anteriores:
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
}
Agora vamos criar um array de livros, serializá-lo, salvar em arquivo e carregar de volta.
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()
{
// Vamos criar um array de livros
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" }
};
// Serialização do array de livros para string
var options = new JsonSerializerOptions { WriteIndented = true };
string json = JsonSerializer.Serialize(books, options);
Console.WriteLine("JSON do array de livros:\n" + json);
// Escrita em arquivo (sincrona)
File.WriteAllText("books.json", json);
// Leitura do arquivo (sincrona)
string jsonFromFile = File.ReadAllText("books.json");
// Desserialização de volta para o array
Book[]? booksFromFile = JsonSerializer.Deserialize<Book[]>(jsonFromFile);
// Mostramos o resultado no console
Console.WriteLine("\nLivros desserializados:");
if (booksFromFile != null)
{
foreach (var book in booksFromFile)
{
Console.WriteLine($"- {book.Title} (autor: {book.Author})");
}
}
}
}
}
O que está acontecendo aqui?
- Criamos um array Book[] e o preenchemos com três livros.
- Usando JsonSerializer.Serialize transformamos o array em uma string JSON bonitinha (a opção WriteIndented deixa o formato legível).
- Gravamos no arquivo, lemos de volta e desserializamos — pronto, temos o array de livros de novo!
- Checamos se todos os dados foram restaurados corretamente.
Verifique que o arquivo "books.json" aparece na pasta do programa. Abra-o, terá algo parecido com este JSON:
[
{
"Title": "Tri tovarishcha",
"Author": "Erikh Mariya Remark"
},
{
"Title": "Master i Margarita",
"Author": "Mikhail Bulgakov"
},
{
"Title": "1984",
"Author": "Dzhordzh Oruell"
}
]
4. Exemplo: serialização de List<T>
Trabalhar com List<Book> é a mesma coisa. O serializador reconhece a coleção e a transforma em um array JSON.
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);
// E desserializamos assim:
List<Book>? loadedBooks = JsonSerializer.Deserialize<List<Book>>(jsonList);
// Conferindo se voltou tudo!
foreach (var book in loadedBooks!)
{
Console.WriteLine($"{book.Title} ({book.Author})");
}
Dá pra serializar uma lista só de inteiros?
Claro! Serialização funciona não só com suas classes, mas também com tipos primitivos:
List<int> numbers = new List<int> { 10, 20, 30, 40 };
string jsonNums = JsonSerializer.Serialize(numbers); // resultado: [10,20,30,40]
List<int>? loadedNums = JsonSerializer.Deserialize<List<int>>(jsonNums);
// loadedNums: List<int> com os mesmos valores
5. Esquema e analogias: como o serializador enxerga coleções?
Pra entender melhor como a serialização de coleções funciona, veja um esquema simples:
graph TD;
A[List[Book] em C#] -->|Serialize| B[Array JSON em string]
B -->|Write| C[Arquivo books.json]
C -->|Read| D[String JSON lida do arquivo]
D -->|Deserialize| E[List[Book] em C#]
Resumo do processo:
- A coleção ou array é serializada como array em JSON ([ ... ]).
- A ordem dos elementos é preservada (a menos que você mexa com configurações específicas).
- Cada elemento da coleção é serializado como seu próprio objeto.
6. Particularidades da serialização de coleções: pontos de atenção
1. null e coleções vazias
Se a coleção for null, o serializador por padrão grava null no JSON. Tenha cuidado: na sua lógica de negócio coleção vazia e null podem não ser a mesma coisa!
Se a coleção estiver vazia (new List<Book>()), o JSON será [] — um array vazio. Isso é útil quando você quer mostrar explicitamente que não há elementos.
2. Desserialização — a ordem importa
A ordem dos elementos no array sempre é preservada. Ou seja, se você serializou três livros numa certa ordem, essa mesma ordem será restaurada.
3. Coleção com objetos de tipos diferentes?
System.Text.Json não tem suporte a polimorfismo “out-of-the-box”. Ou seja, se você tiver, por exemplo, List<Animal> com Dogs e Cats (onde cada um é uma classe derivada), por padrão não dá pra saber ao desserializar “qual era o tipo exato”. Vamos cobrir serialização polimórfica depois; em listas normais, é simples.
7. Erros comuns e mal-entendidos
Erro #1: Serializamos uma coleção, mas esquecemos que ela pode conter objetos com campos privados
JsonSerializer serializa apenas propriedades públicas (e geralmente com getters/setters). Se sua classe for assim:
public class User
{
public string Login { get; set; }
private string Password { get; set; } // Não será serializado!
}
A senha não vai para o JSON — e isso é bom pra segurança. Mas se você queria salvar esse valor, lembre-se de tornar a propriedade pública.
Erro #2: Serialização de coleções com elementos null
Se a coleção contém null, por exemplo: new List<Book> { null, book2 }, então após a serialização o primeiro elemento será null. Na desserialização acontece a mesma coisa! Exemplo de JSON assim:
[null, { "Title": "Voyna i mir", "Author": "Lev Tolstoy" }]
Na prática isso é raro, mas se sua coleção pode ter “buracos”, considere isso na lógica.
Erro #3: Tipo errado na desserialização
Erro comum: você serializou uma lista, mas desserializa num array (ou vice-versa). Isso funciona se os tipos forem compatíveis (Book[] ↔ List<Book>), mas podem surgir nuances se, por exemplo, você tentar desserializar um array de strings para um objeto que não é uma coleção.
GO TO FULL VERSION