Uso de tipo dinámico (Guía de programación de C#)Using type dynamic (C# Programming Guide)

C# 4 introduce un nuevo tipo, dynamic.C# 4 introduces a new type, dynamic. Se trata de un tipo estático, pero un objeto de tipo dynamic omite la comprobación de tipos estáticos.The type is a static type, but an object of type dynamic bypasses static type checking. En la mayoría de los casos, funciona como si tuviera el tipo object.In most cases, it functions like it has type object. En tiempo de compilación, se supone que un elemento con tipo dynamic admite cualquier operación.At compile time, an element that is typed as dynamic is assumed to support any operation. 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.Therefore, you do not have to be concerned about whether the object gets its value from a COM API, from a dynamic language such as IronPython, from the HTML Document Object Model (DOM), from reflection, or from somewhere else in the program. Pero si el código no es válido, los errores se detectan en tiempo de ejecución.However, if the code is not valid, errors are caught at run time.

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.For example, if instance method exampleMethod1 in the following code has only one parameter, the compiler recognizes that the first call to the method, ec.exampleMethod1(10, 4), is not valid because it contains two arguments. La llamada genera un error del compilador.The call causes a compiler error. El compilador no comprueba la segunda llamada al método, dynamic_ec.exampleMethod1(10, 4), porque el tipo de dynamic_ec es dynamic.The second call to the method, dynamic_ec.exampleMethod1(10, 4), is not checked by the compiler because the type of dynamic_ec is dynamic. Por consiguiente, no se notifica ningún error del compilador.Therefore, no compiler error is reported. Pero el error no pasa inadvertido indefinidamente.However, the error does not escape notice indefinitely. Se detecta en tiempo de ejecución y genera una excepción en tiempo de ejecución.It is caught at run time and causes a run-time exception.

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.The role of the compiler in these examples is to package together information about what each statement is proposing to do to the object or expression that is typed as 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.At run time, the stored information is examined, and any statement that is not valid causes a run-time exception.

El resultado de la mayoría de las operaciones dinámicas es dynamic.The result of most dynamic operations is itself 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.For example, if you rest the mouse pointer over the use of testSum in the following example, IntelliSense displays the type (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:Operations in which the result is not dynamic include:

  • Conversiones de dynamic a otro tipo.Conversions from dynamic to another type.
  • Llamadas de constructor que incluyen argumentos de tipo dynamic.Constructor calls that include arguments of type dynamic.

Por ejemplo, el tipo de testInstance en la declaración siguiente es ExampleClass, no dynamic:For example, the type of testInstance in the following declaration is ExampleClass, not dynamic:

var testInstance = new ExampleClass(d);

En la siguiente sección, "Conversiones", se muestran ejemplos de conversión.Conversion examples are shown in the following section, "Conversions."

ConversionesConversions

Las conversiones entre objetos dinámicos y de otro tipo son fáciles.Conversions between dynamic objects and other types are easy. Esto permite al desarrollador cambiar entre el comportamiento dinámico y no dinámico.This enables the developer to switch between dynamic and non-dynamic behavior.

Cualquier objeto se puede convertir implícitamente al tipo dinámico, tal y como se muestra en los ejemplos siguientes.Any object can be converted to dynamic type implicitly, as shown in the following examples.

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.Conversely, an implicit conversion can be dynamically applied to any expression of type dynamic.

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

Resolución de sobrecarga con argumentos de tipo dinámicoOverload resolution with arguments of type dynamic

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.Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type dynamic, or if the receiver of the method call is of type 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.In the following example, if the only accessible exampleMethod2 method is defined to take a string argument, sending d1 as the argument does not cause a compiler error, but it does cause a run-time exception. 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.Overload resolution fails at run time because the run-time type of d1 is int, and exampleMethod2 requires a string.

// 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 RuntimeDynamic language runtime

Dynamic Language Runtime (DLR) es una nueva API en .NET Framework 4.The dynamic language runtime (DLR) is a new API in .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.It provides the infrastructure that supports the dynamic type in C#, and also the implementation of dynamic programming languages such as IronPython and IronRuby. Para obtener más información sobre el entorno DLR, vea Dynamic Language Runtime Overview (Información general sobre Dynamic Language Runtime).For more information about the DLR, see Dynamic Language Runtime Overview.

Interoperabilidad COMCOM interop

C# 4 incluye varias características que mejoran la experiencia de interoperar con API de COM tales como las API de automatización de Office.C# 4 includes several features that improve the experience of interoperating with COM APIs such as the Office Automation APIs. Entre las mejoras se incluye el uso del tipo dynamic y de argumentos opcionales y con nombre.Among the improvements are the use of the dynamic type, and of named and optional arguments.

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.Many COM methods allow for variation in argument types and return type by designating the types as object. Esto requería una conversión explícita de los valores para coordinarlos con variables fuertemente tipadas en C#.This has necessitated explicit casting of the values to coordinate with strongly typed variables in C#. Si se compila con la opción /link (Opciones del compilador de C#), la introducción del tipo dynamic le permite tratar las repeticiones de object en las firmas COM como si fueran de tipo dynamic y así evitar gran parte de la conversión.If you compile by using the /link (C# Compiler Options) option, the introduction of the dynamic type enables you to treat the occurrences of object in COM signatures as if they were of type dynamic, and thereby to avoid much of the casting. 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.For example, the following statements contrast how you access a cell in a Microsoft Office Excel spreadsheet with the dynamic type and without the dynamic type.

// 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];
TitleTitle DESCRIPCIÓNDescription
dynamicdynamic Describe el uso de la palabra clave dynamic.Describes the usage of the dynamic keyword.
Información general sobre Dynamic Language RuntimeDynamic Language Runtime Overview 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).Provides an overview of the DLR, which is a runtime environment that adds a set of services for dynamic languages to the common language runtime (CLR).
Tutorial: Crear y usar objetos dinámicosWalkthrough: Creating and Using Dynamic Objects Ofrece instrucciones paso a paso para crear un objeto dinámico personalizado y para crear un proyecto que acceda a una biblioteca de IronPython.Provides step-by-step instructions for creating a custom dynamic object and for creating a project that accesses an IronPython library.
Cómo: Tener acceso a objetos de interoperabilidad de Office mediante las características de Visual C#How to: Access Office Interop Objects by Using Visual C# Features 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.Demonstrates how to create a project that uses named and optional arguments, the dynamic type, and other enhancements that simplify access to Office API objects.