C# - O tipo de dados Dynamic
A plataforma .NET introduziu na usa última versão um novo tipo de dados na linguagem C# 4.0. |
Estou falando do tipo dynamic.
As linguagens dinâmicas foram muito
populares na década de 80 sendo linguagens versáteis usadas para programação via script onde não existia a verificação de tipos. As linguagens PHP , Ruby e Phyton são exemplos de linguagens dinâmicas sendo menos prolixas e mais simples de usar. Como o compilador só realiza a verificação do tipo em tempo de execução é necessário uma maior atenção do programador para evitar erros. As linguagens IronPhyton e IronRuby são portes das linguagens Phyton e Ruby para a plataforma .NET sendo suportadas pelo DLR.
O
Dynamic Language
Runtime
(DLR)
da
Microsoft
é
um esforço
contínuo
para
trazer
um
conjunto
de
serviços que são executados
em
cima
do
Common Language
Runtime
(CLR)
e
fornece
serviços de tradução
para várias
linguagens dinâmicas.
|
Abaixo vemos a figura que apresenta o DLR dando suporte as linguagens dinâmicas e ao recurso dynamic do C# 4.0:
O tipo dynamic é um tipo estático que é definido pela palavra reservada dynamic sendo que a princípio a variável desse tipo pode ser TUDO, e, em tempo de compilação o tipo dynamic assume qualquer operação.
Mesmo sendo um tipo estático a declaração dynamic faz com que o compilador não realize as validações estáticas sendo que as operações também somente serão avaliadas em tempo de execução.
A sua utilização ou não vai depender de cada caso e do cenário, e, como ele não dá suporte ao Intellisense você deve tomar muito cuidado ao usar esse tipo.
object , var e dynamic qual a
diferença ???? - object e dynamic : são tipos; |
Em linguagens como JavaScript e PHP, as variáveis são fracamente tipadas, e não há necessidade de declarar o tipo de dados que uma variável irá realizar, por isso não há restrições sobre os operadores ou métodos que pode utilizar, por exemplo, o código JavaScript abaixo pode ser usado sem problemas:
// código JavaScript var teste = "Macoratti"; teste += 1; alert(teste); |
resultado ==> Macoratti1 |
Se tentarmos executar o mesmo código usando as linguagens fortemente tipadas da plataforma .NET com C# ou VB .NET teríamos algo assim (usando C#):
/ código C#
static void Main(string[] args)
{
object teste = "Macoratti";
teste += 1;
Console.WriteLine(teste);
Console.ReadKey();
}
Mas Por quê ???
Embora a variável teste seja do tipo object e possa receber qualquer valor, quando atribuímos uma string à mesma, o compilador sabe que não podemos adicionar o valor 1 a uma string e por isso lança uma exceção em tempo de compilação;
Agora vejamos o mesmo código usando o tipo dynamic com a linguagem C# 4.0:
/ código C# 4.0
static void Main(string[] args)
{
dynamic teste = "Macoratti";
teste += 1;
Console.WriteLine(teste);
Console.ReadKey();
}
O compilador agora exibe o resultado : Macoratti1 , pois a expressão teste +=1 , onde teste é um tipo dynamic, não é verificada em tempo de compilação.
As conversões entre os objetos dinâmicos e outros tipos são fáceis e isso permite ao desenvolvedor alternar entre o comportamento dinâmico e não dinâmicos.
Qualquer objeto pode ser convertido implicitamente para o tipo dynamic , conforme mostrado nos exemplos a seguir:
dynamic d1 = 7;
dynamic d2 =
"a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();
A conversão implícita também pode ser aplicada dinamicamente a qualquer
expressão do tipo
dynamic.
int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;
O código completo é dado a seguir na aplicação console DynamicTipo:
using System; namespace DynamicTipo { class Program { static void Main(string[] args) { dynamic teste = "Macoratti"; teste += 1; Console.WriteLine(teste); Console.ReadKey(); dynamic d1 = 7; dynamic d2 = "a string"; dynamic d3 = System.DateTime.Today; dynamic d4 = System.Diagnostics.Process.GetProcesses(); Console.ReadKey(); int i = d1; string str = d2; DateTime dt = d3; System.Diagnostics.Process[] procs = d4; } } } |
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).
Para ilustrar, abaixo temos comandos que mostram como você pode acessar uma célula em uma planilha do Microsoft Excel com e sem a utilização do tipo dynamic:
Sem usar dynamic |
((Excel.Range)excelApp.Cells[1, 1]).Value2
= "Nome"; Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1]; |
Usando dynamic |
excelApp.Cells[1, 1].Value = "Nome"; Excel.Range range2010 = excelApp.Cells[1, 1]; |
No exemplo onde usamos dynamic o acesso à propriedade Value e a conversão para Excel.Range são manipulados pelo binder COM em tempo de execução.
Antes de terminar quero lembrar que apesar do recurso dynamic a linguagem C# não é uma linguagem dinâmica.
Eu sei é apenas C# , mas eu gosto...
Referências:
Usando o tipo dynamic