C# - Apresentando as coleções somente leitura
 Veja como usar as interfaces genéricas somente leitura como IReadOnlyList, IReadOnlyDictionary e IReadonlyCollection para evitar modificações em suas coleções.

Uma coleção representa um conjunto de objetos usados ​​para o armazenamento e recuperação de dados. As coleções permitem que você aloque memória dinamicamente para armazenar elementos e, em seguida, recuperá-los usando uma chave ou índice conforme necessário.

Você pode ter coleções padrão ou genéricas onde as coleções padrão não fornecem a segurança de tipos, mas as coleções genéricas são seguras para tipos. As coleções padrão fazem parte do namespace System.Collections e as coleções genéricas fazem parte do namespace System.Collections.Generic.

Um objeto imutável é definido como um objeto que não pode ser alterado após ter sido criado. Nem todas as coleções são imutáveis, mas você pode usar os tipos de coleção somente leitura no .NET Core, como IReadOnlyList, IReadOnlyDictionary e IReadOnlyCollection para implementar tipos imutáveis. Todos eles fazem parte do namespace System.Collections.Generic.

1- A interface IReadOnlyCollection estende a interface IEnumerable e representa uma interface de coleção básica somente leitura. Ele também inclui uma propriedade Count além dos membros IEnumerable;

2- A interface IReadOnlyList representa uma coleção somente leitura de elementos que podem ser acessados pelo índice e possui a propriedade Count;

3- A interface IReadOnlyDictionary representa uma coleção genérica de pares chave/valor e contém as propriedades Count, Keys e Values;

Para mostrar como usar essas coleções vamos criar um projeto usando o VS 2022 do tipo Console com o nome CShp_ReadOnly.

Neste projeto o arquivo Program esta usando o recurso Instruções de nível superior.

Vamos incluir o código abaixo na classe Program:

var alunos = GetAlunos();

foreach(var aluno in alunos )
    Console.WriteLine(aluno.Nome);

Console.ReadKey();

static IReadOnlyList<Aluno> GetAlunos()          
{
    return new List<Aluno>
   {
       new Aluno
       {
           Id = 1,
           Nome = "Maria",
           Email = "maria@email.com"
       },
       new Aluno
       {
           Id = 2,
           Nome = "Manoel",
           Email = "manoel@email.com"
       }
    };
}
public class Aluno
{
    public int Id { get; set; }
    public string? Nome { get; set; }
    public string? Email { get; set; }
}

Neste código criamos uma coleção de objetos Aluno que é do tipo IReadOnlyList<T> e estamos obtendo os dados e exibindo os nomes dos alunos no console.

Qual a novidade aqui ?

Se examinarmos o código veremos que a coleção apresenta apenas os métodos Count e Capacity e não apresenta mais o método Add, e , assim não podemos mais incluir novos itens na coleção visto que a mesma é imutável.

Além disso podemos expor uma List<T> como uma ReadOnlyCollection<T> usando o método AsReadOnly como mostrado no código abaixo:

using System.Collections.ObjectModel;

var alunos = Teste.ReadOnlyLista;

foreach(var aluno in alunos )
    Console.WriteLine(aluno.Nome);

Console.ReadKey();

public class Aluno
{
    public int Id { get; set; }
    public string? Nome { get; set; }
    public string? Email { get; set; }

    public static List<Aluno> GetAlunos()
    {
        return new List<Aluno>
       {
           new Aluno
           {
               Id = 1,
               Nome = "Maria",
               Email = "maria@email.com"
           },
           new Aluno
           {
               Id = 2,
               Nome = "Manoel",
               Email = "manoel@email.com"
           }
        };
    }
}
class Teste
{

    private static List<Aluno> minhaLista = Aluno.GetAlunos();

    public static ReadOnlyCollection<Aluno> ReadOnlyLista
    {
        get
        {
            return minhaLista.AsReadOnly();
        }
    }
}

Neste código estamos obtendo uma lista de alunos do tipo List<T> e usando o método AsReadOnly() estamos retornando uma ReadOnlyCollection<T>.

Lembrando que podemos simplificar o código da classe Teste usando Expression Bodied Properties:

class Teste
{
    private static List<Aluno> minhaLista = Aluno.GetAlunos();
    public static ReadOnlyCollection<Aluno> ReadOnlyLista => minhaLista.AsReadOnly();
}

Assim este recurso pode ser útil quando você precisar de uma coleção imutável.  No entanto, deve-se observar que, embora esses tipos de coleção somente leitura forneçam uma visualização somente leitura dos dados, eles são apenas invólucros e não fornecem uma cópia imutável da coleção.

E estamos conversados.

"Pois estou convencido de que nem morte nem vida, nem anjos nem demônios, nem o presente nem o futuro, nem quaisquer poderes,nem altura nem profundidade, nem qualquer outra coisa na criação será capaz de nos separar do amor de Deus que está em Cristo Jesus, nosso Senhor."
Romanos 8:38,39

Referências:


José Carlos Macoratti