Criar Classes Dinâmicas usando DynamicObject e ExpandoObject em C# (CSharp)

Aprenda a criar objetos dinâmicos em C# (CSharp).


Autor : Antonio Carlos Ferreira de Azevedo
Postado em : 15/06/2016

Classes Dinâmicas

C# é em sua base uma linguagem de tipagem estática. Isso significa que o compilador precisa saber com antecedência sobre o tipo de dados de uma variável. Na ausência desta informação, o compilador irá lançar um erro de compilação e irá se recusar a compilar o código. Apesar das vantagens oferecidas pelas linguagens de tipagem estática, linguagens dinâmicas têm seu próprio lugar no desenvolvimento de aplicações. Por exemplo, a maioria dos sites desenvolvidos hoje fazer uso de JavaScript, de uma forma ou de outra. Linguagens como Python e Ruby também são populares entre os desenvolvedores. A linguagem C# agora suporta características dinâmicas através Dynamic Language Runtime (DLR). Parte desses recursos incluem tipos dinâmicos, a Classe DynamicObject e ExpandoObject. Este artigo explica esses recursos e fornece exemplos que ilustram como esses recursos são utilizados.

Esta funcionalidade esta presente no CLR NET 4.0 ou superior e é encapsulado no namespace System.Dynamic. Certifique-se de ter importado esse namespace nos exemplos aqui apresentados declarando-o em using conforme abaixo.


using System.Dynamic;


Entendendo os tipos de dados dinâmicos

O compilador C# espera que você especifique claramente o tipo de dados de uma variável antes de compilar o código. Em outras palavras, impõe na compilação a verificação de tipo de dado. Embora isso funcione muito bem para a maioria dos casos, às vezes você pode querer ignorar esta verificação na compilação. Considere, por exemplo, que você deseja executar HTML armazenado em um arquivo externo e você queira trocar as variáveis ​​entre o seu código C# e código de HTML. Nesses casos, o código C# não consegue detectar os tipos de dados usados ​​no HTML em tempo de compilação e você deve ignorar a verificação de tipo. Considerando tais necessidades C# introduziu o tipo de dado dinâmico. Um tipo dinâmico permite que você pule a verificação na compilação. Só em tempo de execução quando o código é realmente executado, os erros (se houver) serão gerado.
A fim de compreender como o tipo dinâmico funciona, vamos desenvolver um aplicativo de console simples e usar variáveis ​​dinâmicas. Comece criando um novo aplicativo de console e, em seguida, adicione o seguinte código no método Main().


static void Main(string[] args)
{
    dynamic MinhaVariavel;
 
    MinhaVariavel = 350;
    Console.WriteLine(MinhaVariavel + " - " + MinhaVariavel.GetType());
 
    MinhaVariavel = "Código Expresso!";
    Console.WriteLine(MinhaVariavel + " - " + MinhaVariavel.GetType());
 
    Console.ReadLine();
}


O código acima declara uma variável MinhaVariavel do tipo dinâmico. A variável é então atribuído um valor inteiro (350) e o tipo de dados é emitido na janela do console. Em seguida, a mesma variável MinhaVariavel é atribuído um valor string e, novamente, seu tipo de dados é emitido.
Veja o resultatdo desta aplicação rodando.


350 - System.Int32
Código Expresso! - System.String


Analisando o resultado do código acima podemos observar que a variável MinhaVariavel inicialmente é do tipo integer e na segunda linha passa a ser do tipo String, uma variável dinâmica pode mudar de dado em tempo de execução, mas atenção, no primeiro momento você pode aplicar funções matemáticas sobre nossa variável, mas ao mudar o tipo para String em tempo de execução se tentarmos executar uma função matemática nossa aplicação vai gerar um erro.


Diferença entre var e dynamic

Em um primeiro momento você pode achar que ao declarar uma variável como var esta será uma variável dynamic, mas não, quando declaramos uma variável como var ao se atribuir um tipo de dado a ela este não pode mais ser alterado, enquanto o tipo de dado dynamic pode ser alterado a qualquer momento.


// Variável definida como inteiro e não pode ser modificada
var a = 100;

// Variável definida como inteiro
dynamic b = 350;

// Definimos a mesma variável como String
b = "www.codigoexpresso.com.br";


Entendendo os Objetos dinâmicos

Normalmente, quando você quer usar algum objeto no seu código, você primeiro precisa criar uma classe e escrever propriedades e métodos nele. Às vezes, porém, você pode querer criar objetos e definir suas propriedades de forma dinâmica. Isso significa que você não terá uma classe contra a qual o compilador possa validar as suas atribuições de propriedade ou chamadas de método. Por que isto e sempre necessário? Considere que você está trocando dados entre C# e sua página. Agora o seu código C# não vai estar ciente dos objetos expostos em sua página em tempo de compilação, por razões óbvias. Assim, em seu código C# você estará atribuindo propriedades e chamando métodos sem saber se eles realmente existem. Erros, (se houver), serão gerados apenas em tempo de execução.


Exemplo passando os dados para sua página utilizando ViewBag

public ActionResult Index()
{
     ViewBag.Mensagem = "Operação realizada com sucesso!";
     ViewBag.Status = "100";
     ViewBag.Data = DateTime.Now;
     
     return View();
}


ASP.NET MVC a partir da versão 3 fornece um objeto ViewBag que permite armazenar valores arbitrários que você deseja passar para o modo de exibição. Como ilustrado no exemplo acima, você simplesmente define propriedades no objeto ViewBag. Na realidade, ViewBag não contém quaisquer definições de propriedade para Mensagem, Status e Data (estes nomes são definido por você e pode-se usar qualquer nome válido). Em outras palavras, você adicionou propriedades dinamicamente ao objeto ViewBag.


Recebendo os dados em sua página utilizando ViewBag

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<span>@ViewBag.Mensagem</span><br />
<span>@ViewBag.Status</span><br />
<span>@ViewBag.Data</span><br />


Criando suas Classes Dinâmicas

O namespace System.Dynamic fornece duas classes que permitem que você crie seus próprios objetos dinâmicos. Eles são - DynamicObject e ExpandoObject. servem para implementar a interface IDynamicMetaObjectProvider, ela permite vincular operações para o objeto subjacente em tempo de execução.


Exemplo de criação de sua Classe Dinâmica

using System;
using System.Dynamic;
using System.Web.Mvc;

namespace ProjetoDinamico.Controllers
{
    public class DynamicController : Controller
    {
      
        public ActionResult Index()
        {
           dynamic MeuSite = new ExpandoObject();

           MeuSite.Nome = "Código Expresso";
           MeuSite.Url = "www.codigoexpresso.com.br";
           MeuSite.Email = "contato@codigoexpresso.com.br";
           MeuSite.Data = DateTime.Now;

           ViewBag.Site = MeuSite;

           return View();
        }
    }
}


Recebendo os dados de sua Classe Dinâmica em sua página

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<span>@ViewBag.Site.Nome</span><br />
<span>@ViewBag.Site.Url</span><br />
<span>@ViewBag.Site.Email</span><br />
<span>@ViewBag.Site.Data</span><br />


Lembre-se que se trocar os nomes em sua View isto vai gerar um erro em tempo de execução, pois não vai encontrar a referencia ao dado solicitado.



Comentários