C# - Programação Funcional - Imutabilidade


Hoje veremos alguns exemplos da programação funcional na linguagem C#.

A programação funcional é mais antiga que os computadores. Suas origens estão na lógica matemática (cálculo lambda). Na programação funcional, programamos com funções e elas não mudam ou modificam nada, apenas mapeiam entrada para saída.

Usando a linguagem C# é possível que você tenha usado conceitos da programação funcional sem ter notado.

Veremos hoje o princípio da imutabilidade do paradigma da programação funcional e como ele existe na linguagem C#, e como podemos criar um tipo imutável.

recursos usados:

O princípio da imutabilidade

A imutabilidade é um aspecto muito importante do paradigma da programação funcional.

A programação imperativa/orientada a objetos geralmente é orientada a estados e a programação funcional incentiva a imutabilidade sem alteração de estado.

Na linguagem C#, temos muitos tipos de imutabilidade, mas eles podem ser categorizados em 2 níveis:

Vejamos o caso das variáveis locais como exemplo:

1- Uma variável local pode ser chamada imutável; se uma vez atribuída, não há como reatribuir um valor a ela;

2- uma variável local também pode ser chamada imutável, se uma vez que seu estado interno for inicializado, não há como modificar seu estado para outro estado.

Temos também outros recursos do C# que podemos usar para tratar a imutabilidade.

A linguagem C# possui uma palavra-chave const para definir constante de tempo de compilação, que não pode ser alterada em tempo de execução.

No entanto, ela funciona apenas para tipos primitivos, string e referência nula:

        static void Main(string[] args)
        {
            const int imutavel1 = 1;
            const string imutavel2 = "https://www.macoratti.net";
            const object imutavel3 = null;
            const Uri imutavel4 = null;
            const Uri imutavel5 = new Uri(imutavel2); // Não compila
        }

Neste código defimimos valores imutáveis usando const.

Esse é um exemplo bem ilustrativo da imutabilidade no C# mas existem outros como:

Como criar tipos imutáveis ?

Se você tem uma classe relativamente simples, pode torná-la imutável facilmente. Esta regra geral se correlaciona com a noção de Objetos de Valor: os objetos de valor são simples e facilmente imutáveis.

Então, como podemos construír tipos imutáveis ?

Para criar uma classe imutável, precisamos pensar que seus membros que não poderão ter os valores alterados após a primeira atribuição, ou seja, são tipos que uma vez inicializados, não poderã mudar o seu estado interno.

Vamos dar um exemplo. Digamos que temos uma classe chamada ProdutoMutavel que representa vários produtos.

    public class ProdutoMutavel
    {
        public string Nome { get; set; }
        public int Quantidade { get; set; }
        public decimal Preco { get; set; }
    }

Para tornar essa classe imutável podemos usar duas abordagens:

1-) Marcar suas propriedades com o atributo somente leitura e criar um construtor parametrizado :

    public class ProdutoImutavel
    {
        public string Nome { get; private set; }
        public int Quantidade { get; private set; }
        public decimal Preco { get; private set; }
        public ProdutoImutavel(string nome, int quantidade, decimal preco)
        {
            Nome = nome;
            Quantidade = quantidade;
            Preco = preco;
        }
    }

2-) Definir propriedades somente leitura, usar um construtor parametrizado e um método estático :

    public class ProdutoImutavel
    {
        public string Nome { get; private set; }
        public int Quantidade { get; private set; }
        public decimal Preco { get; }
        private ProdutoImutavel(string nome, int quantidade, decimal preco)
        {
            Nome = nome;
            Quantidade = quantidade;
            Preco = preco;
        }

        public static ProdutoImutavel GetProduto(string nome,int qtde, decimal preco)
        {
            return new ProdutoImutavel(nome, qtde, preco);
        }
    }

Simples assim.

Mas quais os benefícios em usar uma classe imutável ?

Dentre os benefícios destacamos os seguintes:

Além disso usando tipos imutáveis também não teremos alteração em termos de memória ou desempenho.

Quando podemos usar classes imutáveis ?

Tudo bem, mas me dê alguns motivos para usar as classes imutáveis.

Que tal esses :

  1. Substituir uma struct (tipo de valor) pela classe (tipo de referência)
  2. Classe com campos constantes;
  3. Classe com informações relacionadas à configuração;
  4. Classe com dados mestre (paises, moedas, etc.);
  5. Classe com dados em cache em classes singleton;

Devemos lembrar que a imutabilidade não é um recurso nativo da linguagem C#, e o que estamos fazendo é criar tipos imutáveis usando alguns recursos existentes da linguagem C#, e, portanto existem limitações.

Além disso, a imutabilidade é uma precaução, não uma proteção. O objetivo é impedir que alguém altere os dados por meios "normais" mas isso será possível usando outros recursos como Reflection.

Outro detalhe importante é que para objetos maiores e complexos poderemos ter problemas de desempenho pois a necessidade de criar uma cópia a cada alteração poderá afetar sua aplicação.

E estamos conversados...

"Quão amáveis são os teus tabernáculos, SENHOR dos Exércitos!
A minha alma está desejosa, e desfalece pelos átrios do Senhor; o meu coração e a minha carne clamam pelo Deus vivo."

Salmos 84:1-2

Referências:


José Carlos Macoratti