Uso de tipo dinámico (Guía de programación de C#)

El dynamic tipo es un tipo estático, pero un objeto de tipo dynamic omite la comprobación de tipos estáticos. En la mayoría de los casos, funciona como si tuviera el tipo object. En tiempo de compilación, se supone que un elemento con tipo dynamic admite cualquier operación. Por consiguiente, no tendrá que preocuparse de si el objeto obtiene su valor de una API de COM, de un lenguaje dinámico como IronPython, del Document Object Model (DOM) HTML, de la reflexión o de otro lugar en el programa. Pero si el código no es válido, los errores se detectan en tiempo de ejecución.

Por ejemplo, si la instancia de método exampleMethod1 del código siguiente solo tiene un parámetro, el compilador reconoce que la primera llamada al método, ec.exampleMethod1(10, 4), no es válida porque contiene dos argumentos. La llamada genera un error del compilador. El compilador no comprueba la segunda llamada al método, dynamic_ec.exampleMethod1(10, 4), porque el tipo de dynamic_ec es dynamic. Por consiguiente, no se notifica ningún error del compilador. Pero el error no pasa inadvertido indefinidamente. Se detecta en tiempo de ejecución y genera una excepción en tiempo de ejecución.

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) { }
}

El rol del compilador en estos ejemplos consiste en empaquetar información sobre lo que cada instrucción se propone para el objeto o la expresión con el tipo dynamic. En tiempo de ejecución, la información almacenada se examina y cualquier instrucción que no sea válida genera una excepción en tiempo de ejecución.

El resultado de la mayoría de las operaciones dinámicas es dynamic. Por ejemplo, si se sitúa el puntero del mouse sobre el uso de testSum en el ejemplo siguiente, IntelliSense muestra el tipo (local variable) dynamic testSum.

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

Las operaciones en las que el resultado no es dynamic incluyen:

  • Conversiones de dynamic a otro tipo.
  • Llamadas de constructor que incluyen argumentos de tipo dynamic.

Por ejemplo, el tipo de testInstance en la declaración siguiente es ExampleClass, no dynamic:

var testInstance = new ExampleClass(d);

En la siguiente sección, "Conversiones", se muestran ejemplos de conversión.

Conversiones

Las conversiones entre objetos dinámicos y de otro tipo son fáciles. Esto permite al desarrollador cambiar entre el comportamiento dinámico y no dinámico.

Cualquier objeto se puede convertir implícitamente al tipo dinámico, tal y como se muestra en los ejemplos siguientes.

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

En cambio, una conversión implícita se puede aplicar dinámicamente a cualquier expresión de tipo dynamic.

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

Resolución de sobrecarga con argumentos de tipo dinámico

La resolución de sobrecarga se produce en tiempo de ejecución y no en tiempo de compilación si uno o varios argumentos de una llamada de método tienen el tipo dynamic o si el receptor de la llamada de método es de tipo dynamic. En el ejemplo siguiente, si el único método exampleMethod2 accesible se define para que tome un argumento de cadena, al enviar d1 como argumento no se produce un error del compilador, pero sí se genera una excepción en tiempo de ejecución. La resolución de sobrecarga no se produce en tiempo de ejecución porque el tipo en tiempo de ejecución de d1 es int, y exampleMethod2 requiere una cadena.

// 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);

Dynamic Language Runtime

Dynamic Language Runtime (DLR) es una API introducida en .NET Framework 4. Proporciona la infraestructura que admite el tipo dynamic en C# y también la implementación de lenguajes de programación dinámicos como IronPython e IronRuby. Para obtener más información sobre el entorno DLR, vea Información general acerca de Dynamic Language Runtime.

Interoperabilidad COM

Muchos métodos COM permiten variaciones en los tipos de argumento y el tipo de valor devuelto mediante la designación de los tipos como object. Esto requería una conversión explícita de los valores para coordinarlos con variables fuertemente tipadas en C#. Si se compila con la opción EmbedInteropTypes (opciones del compilador de C#) la introducción del tipo dynamic le permite tratar las repeticiones de object en las signaturas de COM como si fueran de tipo dynamic y así evitar gran parte de la conversión. Por ejemplo, las instrucciones siguientes comparan cómo se accede a una celda de una hoja de cálculo de Microsoft Office Excel con el tipo dynamic y sin el tipo dynamic.

// Before the introduction of dynamic.
((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name";
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];
// After the introduction of dynamic, the access to the Value property and
// the conversion to Excel.Range are handled by the run-time COM binder.
excelApp.Cells[1, 1].Value = "Name";
Excel.Range range2010 = excelApp.Cells[1, 1];
Title Descripción
dynamic Describe el uso de la palabra clave dynamic.
Información general sobre Dynamic Language Runtime Ofrece información general sobre DLR, que es un entorno en tiempo de ejecución que agrega un conjunto de servicios para lenguajes dinámicos en Common Language Runtime (CLR).
Tutorial: Crear y usar objetos dinámicos Ofrece instrucciones paso a paso para crear un objeto dinámico personalizado y para crear un proyecto que acceda a una biblioteca de IronPython.
Procedimiento para acceder a objetos de interoperabilidad de Office mediante características de C# Muestra cómo crear un proyecto que use argumentos opcionales y con nombre, el tipo dynamic y otras mejoras que simplifican el acceso a objetos de la API de Office.