Criar Classes Dinâmicas usando DynamicObject e ExpandoObject em C# (CSharp)
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 />
Criando uma classe Dinâmica atribuindo seu valor
dynamic aluno = new ExpandoObject { Idade = 12, Nome = "Marcelo" };
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.
Links Relacionados
- Arquitetura CQRS
- Arrays em C#(CSharp)
- C#(CSharp) Converter inteiro para Hexadecimal e Hexadecimal para Inteiro
- C#(CSharp) Exemplo de Conversão de um List<> de uma classe qualquer para um DataTable.
- C#(CSharp) Função para verificar se um determinado número é Primo
- Calcular Idade C# (CSharp), diferença anos entre duas datas
- Classe com Métodos de extensão C# (CSharp)
- Classe para Ler e Gravar Cookies - Asp.Net MVC 4 com C# (CSharp)
- Classe para tratar valores nulos vindos de nossa Query SQL, C#(CSharp).
- Classes anônimas em C#(CSharp)
- Comando nameof() C#(CSharp)
- Compare duas strings ignorando maiúsculas e minúsculas C#(CSharp).
- Consulta SQLServer com paginação
- Definir o dia em um DateTime.
- DELETE CASCADE no SqlServer
- Desvendando o Poder da Função STRING_AGG no SQL Server para concatenação de dados
- Diferença entre parâmetros REF e OUT em C#(CSharp)
- Emitir sons pelo auto-falante do computador em C# (CSharp)
- Estrangulando um monólito C#(CSharp)
- Exemplo de acesso a dados com SQL Server em C#.
- Exemplo de consulta em SqlServer para encontrar uma chave Estrangeira
- Explorando Tipos de Dados Personalizados no SqlServer: Utilidade e Impacto na Performance
- Extensões para DataReader, tratando valores de suas consultas SQL (DataReaderExtensions) C#(CSharp)
- Formatar CEP em C# (CSharp)
- Função para devolver data do próximo dia da semana informado C#(CSharp).
- Gerando números randômicos para sorteio de jogos de azar C#(CSharp)
- Grafana Loki e .NET Framework com C#
- Incrementando e decrementando variáveis em C#(CSharp)
- Injeção de dependência
- Ler string de conexão (connectionStrings) do arquivo Web.config Asp.Net MVC co C#(CSharp)
- Métodos de extensão C#
- Ordenando um array com o comando OrderBy C#(CSharp)
- Parar um loop foreach usando o comando break C#(CSharp).
- Recuperar a URL da página anterior em Asp.Net C# (CSharp)
- Recuperar a URL da página atual em Asp.Net C# (CSharp)
- Recuperar para código C# (CSharp) o valor de um componente de nossa página
- Retorna o IP da conexão do Cliente em Asp.Net MVC com C# (CSharp)
- Retorna os dados do Navegador do Cliente em Asp.Net MVC com C# (CSharp)
- Salvando CSV com cabeçalho no SQL Server Management Studio
- Separar String de caracteres C#(CSharp)
- Serilog e .NET Framework com C#
- Tipos de dados em C# (CSharp)
- Tipos de dados primitivos em C#(CSharp)
- Validando Valores nulos vindos de nosso Banco de Dados C#(CSharp)
- Validar Modelos com Data Annotation e Windows Form Application C#(CSharp)
- Verificar se uma string é um digito em C# (CSharp)
Comentários
Adicionamos exemplo de como cria classe dinâmica e já atribuir seu valor.