O que são “Generics” no C# ?

Marcio Nizzola
4 min readJun 20, 2021

--

Muitas vezes precisamos resolver problemas comuns e evitar a reescrita de código, esse é o propósito de qualquer desenvolvedor quando quer ganhar produtividade, sendo assim, se houvesse uma solução “Genérica” para um problema seria ótimo !

Muitas tarefas são comuns, e você gostaria de usar um código que pudesse ser reutilizado com qualquer classe do seu projeto (um CRUD por exemplo).

O que são Generics em C# ?

Quando programamos em C#, definimos nossas classes para múltiplos propósitos, então pensando em podermos “Generalizar” a referência a estes objetos, ainda quando estava no .Net Framework 2.0 foi criado o tipo Genérico (System.Collection.Generic) que veio para ajudar na reutilização de códigos. Criar objetos da classe genérica é semelhante à instanciar um objeto normalmente.

Características dos genéricos do C#

Uma classe genérica pode ser uma classe base, bem como uma classe derivada.

Reusabilidade — Sem fazer alterações de código, a definição do tipo genérico pode ser utilizada para múltiplos propósitos. Por exemplo: o mesmo método genérico pode ser usado para adicionar dois inteiros, float, double, etc.

Tipo de segurança — Embora o genérico forneça opções para usar vários tipos de dados para alcançar o mesmo objetivo, ele é muito seguro para tipagem.

Desempenho — Os genéricos proporcionam melhor desempenho em relação aos tipos normais do sistema, pois reduzem a necessidade de digitação, box e unbox.

Classes e Propriedade Genérica

As classes genéricas são definidas usando o nome da classe seguido por parâmetros do tipo dentro de sinal de maior e menor.

Podemos usar qualquer caractere em vez de T, mas é bastante comum nomear um tipo genérico como “T”.

No exemplo acima, ObjetoExemplo é o nome de classe e T é o parâmetro do tipo. O parâmetro de tipo pode ser usado para os campos, propriedades, tipos de devolução e delegados dentro da classe.

No exemplo acima, Informação é uma propriedade presente na classe ObjetoExemplo do tipo “T”, ou seja, é genérica.

O método Exibir servirá á qualquer tipo de informação.

Nos dois exemplos acima, vimos um parâmetro de tipo único (T) sendo usado para criar uma classe personalizada. Vamos ver como criar uma classe genérica usando dois tipos genéricos no exemplo a seguir.

Instanciar uma classe genérica é semelhante a uma classe regular. Mas, além disso, o tipo de dados tem que ser especificado.

No código acima, instanciamos a classe genérica com dois tipos de dados diferentes.

As classes genéricas também podem ser usadas como uma classe Base/Derivada. Além disso, métodos genéricos podem ser usados dentro de uma classe não genérica.

No exemplo acima, a classe genérica é atribuída com o tipo ao ser herdada.

Além disso, métodos genéricos podem ter tipos de dados primitivos, tipos de dados definidos pelo usuário e parâmetros do tipo T juntos como parâmetros de entrada e os mesmos são aplicáveis para o tipo de retorno.

Além disso, métodos genéricos podem ser usados dentro de uma classe não genérica.

E para utilizar o método basta daí especificar o tipo genérico como abaixo:

Nota — Não é obrigatório especificar o tipo de parâmetro de tipo T explicitamente enquanto chama o método, pois o código inferiria o tipo de dados a partir do valor especificado.

Restrições

A linguagem .NET ainda permite que criemos restrições para os tipos genéricos, são uma forma de permitir que apenas os tipos de objetos definidos sejam aceitos.

Neste caso limitamos que apenas uma classe possa ser passada na definição.

Há outros exemplos:

Na documentação da Microsoft você encontrará várias formas de implementar as restrições. (where (restrição de tipo genérico) — Referência de C# | Microsoft Docs).

Concluindo

Genéricos são fáceis de implementar e fornecem código mais limpo para compreensão e execução. Os suportes angulares representam que a classe/método é um tipo genérico. E o compilador substituirá todos os espaços reservados pelo tipo de dados fornecido. Como é feito no tempo de compilação, quaisquer erros humanos ao implementá-lo serão lançados como erros de compilação.

Um exemplo de uso que sempre faço, é quando utilizar repositórios com Entity Framework, criar classes Base onde já deixo as operações Crud prontas e faço a herança dela nos outros repositórios, economizando código.

Num próximo post demostrarei como fazê-lo.

--

--

Marcio Nizzola
Marcio Nizzola

Written by Marcio Nizzola

Microsoft MVP | Software Architect na CI&T | Prof. da Etec Itu | Membro Fundador da Comunidade Itu Developers.

No responses yet