Usar o tipo dinâmico

O tipo dynamic é estático, mas um objeto do tipo dynamic ignora a verificação de tipo estático. Na maioria dos casos, ele funciona como se tivesse o tipo object. O compilador pressupõe que um elemento dynamic dá suporte a qualquer operação. Portanto, você não precisa determinar se o objeto obtém seu valor de uma API COM, de uma linguagem dinâmica como o IronPython, do HTML DOM (Modelo de Objeto do Documento), a reflexão ou de algum outro lugar no programa. No entanto, se o código não for válido, os erros aparecerão em tempo de execução.

Por exemplo, se método de instância exampleMethod1 no código a seguir tiver apenas um parâmetro, o compilador reconhecerá que a primeira chamada para o método, ec.exampleMethod1(10, 4), não será válido porque ele contém dois argumentos. Essa chamada causa um erro do compilador. O compilador não verifica a segunda chamada para o método, dynamic_ec.exampleMethod1(10, 4), porque o tipo dynamic_ec é dynamic. Portanto, nenhum erro de compilador é relatado. No entanto, o erro não passa despercebido indefinidamente. Ele aparece em tempo de execução e causa uma exceção em tempo de execução.

static void Main(string[] args)
{
    ExampleClass ec = new ExampleClass();
    // The following call to exampleMethod1 causes a compiler error
    // if exampleMethod1 has only one parameter. Uncomment the line
    // to see the error.
    //ec.exampleMethod1(10, 4);

    dynamic dynamic_ec = new ExampleClass();
    // The following line is not identified as an error by the
    // compiler, but it causes a run-time exception.
    dynamic_ec.exampleMethod1(10, 4);

    // The following calls also do not cause compiler errors, whether
    // appropriate methods exist or not.
    dynamic_ec.someMethod("some argument", 7, null);
    dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
    public ExampleClass() { }
    public ExampleClass(int v) { }

    public void exampleMethod1(int i) { }

    public void exampleMethod2(string str) { }
}

A função do compilador nesses exemplos é reunir informações sobre o que cada instrução está propondo fazer para o objeto ou expressão que tem o tipo dynamic. O runtime examina as informações armazenadas e qualquer instrução que não seja válida causa uma exceção em tempo de execução.

O resultado de operações mais dinâmicas é dynamic. Por exemplo, se você passar o ponteiro do mouse sobre o uso de testSum no exemplo a seguir, o IntelliSense exibirá o tipo (variável local) testSum dinâmico.

dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);

As operações em que o resultado não é dynamic incluem:

  • Conversões de dynamic em outro tipo.
  • Chamadas de construtor que incluem argumentos do tipo dynamic.

Por exemplo, o tipo de testInstance na seguinte declaração é ExampleClass e não dynamic:

var testInstance = new ExampleClass(d);

Conversões

As conversões entre objetos dinâmicos e outros tipos são fáceis. As conversões permitem que o desenvolvedor alterne entre o comportamento dinâmico e o não dinâmico.

Você pode converter qualquer um para dynamic implicitamente, conforme mostrado nos exemplos a seguir.

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

Por outro lado, você pode aplicar dinamicamente qualquer conversão implícita a qualquer expressão do tipo dynamic.

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

Resolução de sobrecarga com argumentos de tipo dynamic

A resolução de sobrecarga ocorre em tempo de execução em vez de em tempo de compilação se um ou mais dos argumentos em uma chamada de método tem o tipo dynamic ou se o receptor da chamada do método é do tipo dynamic. No exemplo a seguir, se o único método exampleMethod2 acessível for definido para obter um argumento de cadeia de caracteres, enviar d1 como o argumento não causará um erro de compilador, mas causará uma exceção de tempo de execução. A resolução de sobrecarga falha em tempo de execução porque o tipo de tempo de execução de d1 é int e exampleMethod2 requer uma cadeia de caracteres.

// Valid.
ec.exampleMethod2("a string");

// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);

runtime de linguagem dinâmico

O DLR (tempo de execução de linguagem dinâmica) fornece a infraestrutura que dá suporte ao tipo dynamic em C# e também à implementação das linguagens de programação dinâmicas como IronPython e IronRuby. Para obter mais informações sobre o DLR, consulte Visão geral do Dynamic Language Runtime.

interoperabilidade COM

Muitos métodos COM permitem variação nos tipos de argumento e tipo de retorno, especificando os tipos como object. A interoperabilidade COM exigiu a conversão explícita dos valores para coordenar com variáveis fortemente tipadas no C#. Se você compilar usando a opção EmbedInteropTypes (opções do compilador C#), a introdução do tipo dynamic permitirá tratar as ocorrências de object em assinaturas COM, como se fossem do tipo dynamic e, portanto, evitar grande parte da conversão. Para obter mais informações sobre como usar o tipo dynamic com objetos COM, confira o artigo sobre Como acessar objetos de interoperabilidade do Office usando recursos C#.

Título Descrição
dinâmico Descreve o uso da palavra-chave dynamic.
Visão geral do Dynamic Language Runtime Fornece uma visão geral do DLR, que é um ambiente de tempo de execução que adiciona um conjunto de serviços para as linguagens dinâmicas para o CLR (Common Language Runtime).
Passo a passo: Criando e usando objetos dinâmicos Fornece instruções passo a passo para criar um objeto dinâmico personalizado e para criar um projeto que acessa uma biblioteca IronPython.