.NET 8 - Frozen Collections


   Hoje vou apresentar novo recurso Frozen Collections do .NET 8.0.

As "Frozen Collections" são um recurso previsto para o .NET 8 que permitem criar coleções imutáveis altamente eficientes em termos de desempenho e uso de memória.

Uma coleção imutável é aquela em que os elementos não podem ser adicionados, removidos ou modificados depois de criada. Isso oferece benefícios como a segurança da thread e a prevenção de erros causados por modificações acidentais.

No .NET 8, estão previstos dois tipos de coleções imutáveis: FrozenSet<T> e FrozenDictionary<TKey, TValue>.

Apresentando Frozen Collections

Vamos entender primeiro oque significa o termo Frozen Collections usando como exemplo um projeto Console.

Para isso vamos usar o VS 2022 Preview e criar um projeto Console App usando a versão do  .NET 8.0 preview :

E para poder usar a versão do C# 12 no projeto teremos que incluir no arquivo de projeto a tag:
<LangVersion>preview</LangVersion> :

<Project Sdk="Microsoft.NET.Sdk">

   <
PropertyGroup>
    <
OutputType>Exe</OutputType>
    <
TargetFramework>net8.0</TargetFramework>
    <
ImplicitUsings>enable</ImplicitUsings>
    <
LangVersion>preview</LangVersion>
    <
Nullable>enable</Nullable>
    </
PropertyGroup>
</
Project>

Vamos analisar o código definido no projeto mostrado a seguir:
 
using System.Collections.Frozen;
using
System.Collections.Immutable;
using
System.Collections.ObjectModel;

List<int> listaNormal = new List<int> { 1, 2, 3 };
ReadOnlyCollection<
int> listaReadOnly = listaNormal.AsReadOnly();
FrozenSet<
int> frozenSet = listaNormal.ToFrozenSet();
ImmutableList<
int> listaImutavel = listaNormal.ToImmutableList();

listaNormal.Add(4);

Console.WriteLine($"Lista contador: {listaNormal.Count}");
Console.WriteLine(
$"listaReadOnly contador: {listaReadOnly.Count}");
Console.WriteLine(
$"FrozenSet contador: {frozenSet.Count}");
Console.WriteLine(
$"listaImutavel contador: {listaImutavel.Count}");

 

Executando o projeto teremos o seguinte resultado:

Agora vamos considerar os seguinte :

- Temos a lista normal que poderá ser alterada e vai refletir isso;

- A lista listaReadOnly é apenas uma "visualização" do objeto a partir do qual foi criada. Portanto, se você atualizar a lista a partir da qual ela foi originalmente criada, listaReadOnly também refletirá essa alteração. O usuário de uma listaReadOnly simplesmente não tem como modificar o estado interno da própria lista.

- Uma coleção congelável - frozenSet -  é uma coleção que pode sofrer alteração até ficar congelada. Uma vez congelada, ela não reflete mais as alterações feitas. É por isso que vemos que o resultado da contagem é igual 3 em vez de 4 (como em listaReadOnly).

- A lista imutável também contém apenas 3 itens e assim não foi alterada, então como a lista imutável difere do nosso objeto congelado ?

Neste exemplo, existem 2 diferenças principais.

- Primeiro, o objeto congelado - frozenSet - é um conjunto e não uma lista (motivo principal: não há FrozenList ou FrozenCollection). Um conjunto não está ordenado e não pode conter elementos duplicados. (Isso pode mudar até o lançamento final do .NET 8)

- O segundo e principal fator: as coleções imutáveis têm maneiras eficientes de modificar a lista criando uma nova. Assim podemos ter:

var listaImutavel2 = listaNormal.ToImmutableList();

// Isso criará uma nova lista imutável
var
novaLista = listaImutavel2.Add(2);

Console.WriteLine(
$"listaImutavel2 contador: {listaImutavel2.Count}");
Console.WriteLine(
$"novaLista contador: {novaLista.Count}");
 

Aqui estamos criando uma nova lista imutável chamada novaLista mas listaImutavel2 foi alterada e agora passa a ter 4 elementos.

Resultado:



Não podemos encontrar esse comportamento com coleções congeladas.

No momento, o .NET8 conhece basicamente dois tipos de coleções congeladas:

Estas coleções não possuem os métodos Add nem Remove.

Surge a pergunta... Por que temos que introduzir esse conceito ? 

Não podemos usar a abordagem atual de objetos somente leitura ou imutáveis ?

Bem, sim e não. 

A proposta é que os frozen objects ou objetos congelados, por terem essas restrições quanto a alteração, possam trazer benefícios de desempenho.

E estamos conversados.

"Sabemos que permanecemos nele, e ele em nós, porque ele nos deu do seu Espírito.
E vimos e testemunhamos que o Pai enviou seu Filho para ser o Salvador do mundo."
1 João 4:13,14

Referências:


José Carlos Macoratti