C# - Tipos dinâmicos


 Hoje veremos o que são tipos dinâmicos definidos pela palavra-chave dynamic.

Há muito tempo atrás, a versão o C# 4.0 (.NET 4.5) introduziu um novo tipo de dados que evita a verificação do tipo em tempo de compilação.

Apenas para recordar, quando você declara variáveis no escopo do método elas podem ter um tipo implícito var, e, uma variável local de tipo implícito é fortemente tipada como se você tivesse declarado um tipo.

Dessa forma as declarações abaixo são equivalentes:

var i = 100; // implicitamente tipada
int i = 100; 
//explicitamente tipada

Tipos Dinâmicos

Um tipo dinâmico não sofre a verificação de tipo em tempo de compilação, o tipo é resolvido em tempo de execução. O tipo é um tipo estático, mas um objeto do tipo dynamic ignora a verificação de tipo estático.

Um tipo dinâmico pode ser definido usando a palavra-chave dynamic :

dynamic variavelDinamica = 100;

Neste caso o compilador compila os tipos dinâmicos em tipos objetos, e, para o exemplo acima teríamos:

object variavelDinamica = 100;

O tipo real da variável dinâmica será resolvido em tempo de execução. Você pode verificar o tipo da variável dinâmica, conforme abaixo:

using static System.Console;
namespace CShp_TiposDinamicos
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic variavelDinamica1 = 1;
            dynamic variavelDinamica2 = "Macoratti.net";
            dynamic variavelDinamica3 = true;
            WriteLine($"variavelDinamica1 => {variavelDinamica1.GetType().ToString()}");
            WriteLine($"variavelDinamica2 => {variavelDinamica2.GetType().ToString()}");
            WriteLine($"variavelDinamica3 => {variavelDinamica3.GetType().ToString()}");
            ReadLine();
        }
    }
}

Um tipo dinâmico muda o seu tipo em tempo de execução com base no valor da expressão do lado direito do operador de atribuição '=' .

Assim, uma variável dinâmica pode ter qualquer tipo e seu tipo pode mudar em tempo de execução.

using System;
using static System.Console;
namespace CShp_TiposDinamicos
{
    class Program
    {
        static void Main(string[] args)
        {
            dynamic variavelDinamica = 100;
            WriteLine($"variavelDinamica => {variavelDinamica.GetType().ToString()}");
            variavelDinamica = "Macoratti .net!!";
            WriteLine($"variavelDinamica => {variavelDinamica.GetType().ToString()}");
            variavelDinamica = true;
            WriteLine($"variavelDinamica => {variavelDinamica.GetType().ToString()}");
            variavelDinamica = DateTime.Now;
            WriteLine($"variavelDinamica => {variavelDinamica.GetType().ToString()}");
            ReadLine();
        }
    }
}

A consequência é que o desempenho cai e você perda o recurso de verificação em tempo de compilação.

Métodos e propriedades do Tipo Dinâmico

Se você atribuir um objeto de classe a um tipo dinâmico, o compilador não verificará se o nome dos métodos e propriedades de um tipo dinâmico que contém o objeto de classe personalizado estão corretos ou existem em tempo de compilação.

using static System.Console;
namespace CShp_TiposDinamicos
{
    public class Aluno
    {
        public int AlunoId { get; set; }
        public string Nome { get; set; }
        public void ExibeNome()
        {
            WriteLine($"Nome: {Nome}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            dynamic dynamicAluno = new Aluno();                      
            dynamicAluno.Nome = "Macoratti.net";
            dynamicAluno.ExibeNome();

            dynamicAluno.MetodoInexistente();
            ReadLine();
        }
    }
}

O compilador não vai emitir nenhum erro para o método MetodoInexistente() pois ele não realiza a verificação de tipo para os tipos dinâmicos em tempo de compilação.

Você vai obter um erro em tempo de execução conforme mostra a figura acima á direita.

Tipos dinâmicos como parâmetros

Um método pode ter parâmetros do tipo dinâmico de forma a poder aceitar qualquer tipo de parâmetro em tempo de execução.

using static System.Console;
namespace CShp_TiposDinamicos
{
    class Program
    {
        static void ExibirValor(dynamic valor)
        {
            System.Console.WriteLine(valor);
        }
        static void Main(string[] args)
        {
            ExibirValor("Macoratti .net!!");
            ExibirValor(100);
            ExibirValor(100.50);
            ExibirValor(true);
            ExibirValor(System.DateTime.Now);
            ReadLine();
        }
    }
}
 

Conclusão

Sinceramente, não é uma boa ideia usar tipos dinâmicos na maioria dos casos, pois seus programas vão ficar mais lentos, e, você perde o benefício da verificação em tempo de compilação.

Existem poucos casos nos quais usar tipos dinâmicos traz algum benefício. Um deles seria tornar bibliotecas externas mal projetadas mais fáceis de usar.

Um dos usos do tipo dynamic esta em melhorar a experiência de interagir com APIs COM, como a API  Office Automation.

Muitos métodos COM permitem a variação de tipos de argumentos e tipo de retorno, designando os tipos de objeto, isto obriga a conversão explícita dos valores para coordenar com variáveis fortemente tipadas em C #.

Se você compilar usando a opção /link, a introdução do tipo dinâmico permite que você trate as ocorrências de objeto COM em assinaturas, como se fossem do tipo dynamic, evitando assim a realização da conversão explícita (casting).

Em suma, a palavra-chave dynamic fornece acesso ao Dynamic Language Runtime (DLR) que é uma camada de funcionalidade sobre o CLR mas que salvo raríssimos casos traz algum real benefício ao programador C#.

"Respondeu Jesus: O meu reino não é deste mundo; se o meu reino fosse deste mundo, pelejariam os meus servos, para que eu não fosse entregue aos judeus; mas agora o meu reino não é daqui."
João 18:36

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti