Mostrando entradas con la etiqueta Reflection. Mostrar todas las entradas
Mostrando entradas con la etiqueta Reflection. Mostrar todas las entradas

domingo, 17 de agosto de 2014

Pregunta C# (4 de 20): ¿Cómo Obtener la Ubicación de una Aplicación de Consola en C#?

Índice

0. Introducción
1. Contexto
1.1 ¿Qué es una aplicación consola?
1.2 Aplicaciones consola en .NET
2. Obtención de la Ubicación de una Aplicación Consola en Ejecución
2.1 Clase System.Reflection.Assembly
2.2 Método Path.GetDirectoryName(string)
3. Aplicación
4. Recursos
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

Esta es la pregunta número 4 (de 20) del curso de Twenty C# Questions Explained de Microsoft Virtual Academy. En esta oportunidad vamos a conocer el proceso para la obtención de la ubicación en disco de un assembly que se haye en ejecución. Esto nos puede resultar útil, por ejemplo, para escribir o leer un archivo binario o de texto directamente desde esa ubicación como recurso de almacenamiento del estado de la aplicación o de la persistencia de los datos del usuario.

1. Contexto

1.1 ¿Qué es una aplicación consola?

Una aplicación consola consiste en un ambiente de trabajo basado en texto. Este ambiente está compuesto naturalmente por dos partes bien definidas:
  1. La entrada estándar: teclado
  2. La salida estándar: el monitor (o la pantalla)
La interacción entre el usuario y el sistema basado en consola se realiza a través de comandos textuales (uso de la entrada estándar). Estos comandos ejecutan operaciones y una vez finalizada su ejecución presentan (aunque no necesariamente) el resultado al usuario en la salida estándar.

Los sistema operativos modernos (e.g., Windows, MacOS, o aquellos basados en Unix) cuentan con este medio de interacción para controlar o llevar a cabo tareas administrativas o inclusive en la actualidad se siguen utilizando software de producción empresarial. En el caso del sistema operativo Windows, éste viene integrado con el programa COM.EXE; con este programa podemos indicar al sistema, por ejemplo, para la navegación entre directorios de usuario o programa, manipular archivos, ejecutar otros programas, etc. En la Figura 1 una captura de pantalla de la ejecución de COM.EXE.
CMD.EXE
Figura 1. CMD.EXE.

Para operaciones administrativas avanzadas del sistema operativo Windows, Microsoft tiene a disposición otro entorno similar al anterior pero aún más robusto y poderoso, debido a que se trata de un marco de trabajo para la automatización y configuración de tareas administrativas gracias a su propio lenguaje de scripting (o instrucciones diseñadas para tareas específicas) [3]: Windows PowerShell.
Windows PowerShell
Figura 2. Windows PowerShell.

1.2 Aplicaciones consola en .NET

Microsoft .NET Framework cuentan con los artefactos de software para la la creación, ejecución de aplicaciones basadas en consola. Estas aplicaciones las podemos crear directamente usando un editor de texto plano (e.g., Notepad++) o de manera más cómoda y ágil sobre el entorno de desarrollo integrado Visual Studio. (Muchos de los seguidores de este blog ya habrán visto que los ejemplos de ejecución se llevan a cabo en un ambiente como este, y que la escritura de los programas de demostración se escriben casi en su totalidad en Notepad++.)

Continuando, en el caso de Visual Studio la creación de una aplicación consola lo podemos hacer siguiendo estos pasos:
  1. Menú File
  2. Submenú New
  3. Comando Project...
  4. Sección Visual C#
  5. Sub-sección Windows
  6. Selección de la plantilla Console Application
  7. Asignamos un nombre y una ubicación al proyecto y a la solución
  8. Clic en OK
Creación aplicación consola en Visual Studio 2013
Figura 3. Creación aplicación consola en Visual Studio 2013.

2. Obtención de la Ubicación de una Aplicación de Consola en Ejecución

Ahora que hemos comprendido los esenciales de lo que se entiende por una aplicación consola, pasemos a explicar los artefactos necesarios para obtener la ubicación de una aplicación de este tipo, además de una demostración en código C# sobre los resultados prácticos de la implementación de estos.

2.1 Clase System.Reflection.Assembly


La clase Assembly [10] (N:System.Reflection) representa la construcción modular de un assembly (cfr. Creación y Uso de un Módulo) en el Framework .NET. Esta clase es capaz de describir los artefactos integrales de la biblioteca de clases del Framework, como también los propios creados por un programador. Además, ofrece miembros (métodos, precisamente) que permiten cargar un assembly en caliente (con esta expresión me refiero a la posibilidad de cargar nuevos artefactos del modelo, o componentes de terceros, una vez el proyecto haya sido construido (build time) el componente).

Lo que nos interesa en particular de esta clase es el método GetExecutingAssembly [6]. Con este método obtenemos el assembly que contiene la aplicación en ejecución. Esta es su firma:

public static Assembly GetExecutingAssembly()

Como mencionamos obtiene una instancia del assembly en ejecución, una vez obtenido podemos utilizar la propiedad Location [7] para la representación en cadena de caracteres de la dirección en disco en donde se haya el assembly:

public virtual string Location { get; }

2.2 Método Path.GetDirectoryName(string)

A continuación el artefacto que requerimos para mostrar la información de un directorio específico (el obtenido con la propiedad Location) es el método GetDirectoryName [8] (clase System.IO.Path). Su firma:

public static string GetDirectoryName(string path)

3. Aplicación

Ahora que ya contamos con los fundamentos requeridos, pasemos a construir un ejemplo muy práctico y sencillo sobre cómo mostrar en pantalla de la consola la ubicación actual de un assembly que crearemos a mano con el uso de Notepad++ como editor de código fuente C#.

En la línea 17 utilizamos la propiedad Location para obtener la ubicación en disco del assembly ObtencionUbicacionAssembly.exe, el cual se haya en ejecución. La representación de esta ubicación es una cadena de caracteres la cual la asignamos a la variable ubicacion (tipo string). Más adelante, línea 21-22, utilizamos el método GetDirectoryName al cual le pasamos como argumento la ubicación almacenada en la variable ubicacion:

Path.GetDirectoryName(ubicacion)


Este método retorna la representación string que al mismo tiempo sirve como argumento del método WriteLine, el se encarga de presentar en pantalla (salida estándar) del nombre del directorio donde se encuentra el assembly ObtencionUbicacionAssembly.exe.

Compilación:


  1. csc /target:exe ObtencionUbicacionAssembly.cs

Ejecución assembly:


  1. .\ObtencionUbicacionAssembly.exe

> Prueba de ejecución (ideone.com).

> Prueba de ejecución (local):
Ejecución assembly ObtensionUbicacionAssembly.exe
Figura 4. Ejecución assembly ObtensionUbicacionAssembly.exe.

4. Recursos

El recuso multimedial presentando en el curso Twenty C# Questions Explained en Microsoft Virtual Academy:

5. Conclusiones

Hemos comprendido el proceso de obtención de la dirección en disco de un assembly en ejecución, el cual nos puede resultar muy útil cuando, por ejemplo, queremos realizar operaciones de manipulación de archivos de texto plano o binarios desde disco. Con las herramientas que nos ofrece el Framework .NET podemos realizar estas tareas de forma sencilla y directa (el ejemplo escrito en la sección 4 lo demuestra). En la próxima pregunta explicaremos cómo invocar el constructor de clase base.

6. Glosario

  • Assembly
  • Directorio
  • IDE
  • Locación
  • Microsoft
  • PowerShell
  • Recurso
  • Ubicación
  • Visual Studio

7. Literatura & Enlaces

[1]: Twenty C# Questions Explained - http://www.microsoftvirtualacademy.com
[2]: Console application - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/Console_application
[3]: Windows PowerShell - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/Windows_PowerShell
[4]: Assembly Class (System.Reflection) - http://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx
[5]: R1-3 Creación y Uso de un Módulo | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2013/10/r1-3-creacion-y-uso-de-un-modulo.html
[6]: Assembly.GetExecutingAssembly Method (System.Reflection) - http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getexecutingassembly(v=vs.110).aspx
[7]: Assembly.Location Property (System.Reflection) - http://msdn.microsoft.com/en-us/library/system.reflection.assembly.location(v=vs.110).aspx
[8]: Path.GetDirectoryName Method (System.IO) - http://msdn.microsoft.com/en-us/library/system.io.path.getdirectoryname(v=vs.110).aspx


J

viernes, 13 de junio de 2014

Receta No. 3-18 en C#: Cómo Crear un Tipo Dinámico Personalizado

Tabla de Contenido

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
3.1 Clase DynamicObject
3.1.1 Método TryGetMember
3.1.2 Método TrySetMember
3.2 Ejemplo de herencia de DynamicObject
4. Práctica: Código Fuente C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

Esta última receta de la serie dominios de aplicación, reflection, y metadatos, aprenderemos cómo crear un tipo personalizado de forma dinámica: establecimiento y recuperación de miembros (propiedades). Usaremos una de las clases introducidas en DLR (.NET Framework 4.0): DynamicObject. Esta clase nos proveerá la maquinaria necesaria para la agregación de propiedades, métodos, índices, &c. a un tipo en tiempo de ejecución. (Los ejemplos mostrados representan una introducción a DLR, que desde luego, será extendida en futuros artículos y/o recetas.)

1. Problema

Ahora damos a paso a un nivel más abstracto y exigente: requerimos de un método que nos permita la adición de comportamiento personalizado a un tipo, y que en consecuencia podamos invocar sus miembros de forma dinámica.

2. Solución

El nombre de espacios System.Dynamic (que hace parte de .NET Framework y que principalmente agrega funcionalidades dinámicas de lenguaje a la CLR) contiene la clase base DynamicObject que nos va a permitir especificar comportamiento dinámico en tiempo de ejecución. Esta clase tendremos que extenderla y sobrescribir los métodos virtual TryXXX (XXX para referirse a los postfijos de la nomenclatura).

3. Discusión de la Solución

3.1 Clase DynamicObject


La clase DynamicObject, es la clase base que facilita la especificación de comportamiento dinámico en tiempo de ejecución para los tipos derivados de esta. No es posible crear instancias directas de esta clase, para lograrlo tendremos que crear una jerarquía de herencia y crear subtipos que hereden de DynamicObject y sobrescribir varios de sus miembros que inician con el prefijo Try (en la Figura 1 [1] se enumeran varios de estos métodos).
Métodos virtual de la clase DynamicObject
Figura 1. Métodos virtual de la clase DynamicObject.
De acuerdo con la documentación de esta clase en [2] es importante incluir (literalmente) este comentario:
"The DynamicObject class enables you to define which operations can be performed on dynamic objects and how to perform those operations. For example, you can define what happens when you try to get or set and object property, call a method, or perform standard mathematical operations such as addtion and multiplication."
Además, esta nota:
Nota sobre el uso de ExpandoObject y IDynamicMetaObjectProvider
Figura 2. Nota sobre el uso de ExpandoObject y IDynamicMetaObjectProvider [2].

Adicionalmente, el hecho de contar con tipos personalizados que deriven de esta clase nos va a permitir crear definiciones de código más intuitivas para los clientes del tipo concreto, por ejemplo:

En lugar de tener una definición como esta

obj.SetProperty ("Contador", 1);

los métodos sobrescritos de DynamicObject en una subclase, facilitan este medio 

obj.Contador = 1;

Desde luego que para nosotros esta última definición es mucho más intuitiva, pues resulta más simple y directa en cuanto a especificación sintáctica (como las propiedades -cfr. Propiedades en C#-)

Para lograr este grado de afinidad sintáctica tendremos que sobrescribir los métodos:
  • TryGetMember
  • TrySetMember

3.1.1 Método virtual TryGetMember

El método TryGetMember [6] se invoca implícitamente cuando intentamos obtener un valor por medio de una propiedad. En la versión sobrescrita en la subclase (herencia de DynamicObject) se especifica el comportamiento dinámico para las operaciones de obtención de valores. Esta es su firma [5]:

public virtual bool TryGetMember(GetMemberBinder binder, out Object result)

Descripción puntual:
  • Parámetros:
    • binder: es el generador de la información del objeto que invoca el comportamiento dinámico.
    • result: resultado de la operación de la operación de obtención de valor (debe establecer un valor independiente de si se ha encontrado un valor o no, esto debido a que su especificación incluye el modificador out).
  • Retorno: true si la operación de establecimiento de valor fue satisfactoria, false en caso contrario. (En este último caso se suelen lanzar excepciones.)

3.1.2 Método virtual TrySetMember

El método TrySetMember [5] permite especificar las operaciones que se han de llevar a cabo para el establecimiento de valores de un miembro. Este método puede ser sobrescrito por el tipo derivado de DynamicObject, y esencialmente se usa para especificar el comportamiento dinámico que de ejecutarse al cambiar el valor de una propiedad. Esta es su firma:

public virtual bool TrySetMember(SetMemberBinder binder, Object value)

Descripción puntual:
  • Parámetros:
    • binder: es el generador de la información del objeto que invoca el comportamiento dinámico.
    • value: instancia de object con la información a establecer sobre el miembro (e.g., propiedad)
  • Retorno: true si la operación de establecimiento de valor fue satisfactoria, false en caso contrario.

3.2 Ejemplo de herencia de DynamicObject

Para facilitar la comprensión del uso de la clase DynamicObject, he decidido hacer una adaptación de código fuente del ejemplo presentado por Anoob Madhusudanan en su artículo acerca de las capacidades dinámicas de .NET 4.0 en [6]:

Archivo de código fuente ClaseDinamica.cs [enlace alternativo]:
En la línea 7 especificamos que la clase ClaseDinamica hereda directamente desde DynamicObject. Creamos una instancia de la colección clave/valor Dictionary<TKey, TValue> [7] para almacenar los miembros que agregamos dinámicamente a una instancia de la clase dinámica ClaseDinamica.

Continuando, en las líneas 19-30 sobrescribimos el método TryGetMember para recuperar el valor de un miembro agregado dinámica. La operación contraria ocurre con el método sobrescrito TrySetMember (líneas 38-51). Con el método TryInvokeMember (líneas 60-71) invocamos un miembro (delegado) utilizando las capacidades dinámicas heredadas de la clase DynamicObject. Más adelante, en las líneas 77-80, sobrescribimos el método GetDynamicMemberNames para descubrir las miembros agregados en tiempo de ejecución a la instancia de ClaseDinamica.


En la región de código cliente, líneas 82-103, definimos una variable del tipo dynamic (cfr. Invocación Dinámica de Miembros de un Tipo) con el identificador -dyn-. Envolvemos una instancia (línea 88) de ClaseDinamica sobre la variable anterior. Más adelante, en la línea 82 creamos de forma dinámica la propiedad Contador y le asignamos el valor literal entero 13. (Para este caso se ha invocado implícitamente el método TrySetMember).



Por otro lado, sobre la línea 95 creamos un delegado a partir del delegado genérico Action<T> (cfr. Tipos Genéricos en C# - Parte 8: Delegados Genéricos) con la expresión lambda texto => Console.WriteLine (texto). A continuación, en la línea 98, lo asignamos al miembro EscribirEnConsola. Para finalizar, invocamos el delegado recién creado y asignado y le pasamos como argumento la representación string de la propiedad dinámica Contador.

Compilación:


  1. csc /target:exe ClaseDinamica.cs

Ejecución assembly:


  1. .\ClaseDinamica.exe

Resultado:
Prueba de ejecución de instancia de la clase dinámica ClaseDinamica
Figura 2. Prueba de ejecución de instancia de la clase dinámica ClaseDinamica.

4. Práctica: Código Fuente C#

Sección idónea para que afiancemos el entendimiento sobre las potencialidades de la herencia de DynamicObject. Creamos la herencia correspondiente, y agregaremos miembros de forma dinámica a una instancia de la clase hija (subclase).

Archivo de código fuente DiccionarioDinamico.cs [enlace alternativo]:
Compilación:


  1. csc /target:exe DiccionarioDinamico.cs

Ejecución assembly:


  1. .\DiccionarioDinamico.exe

Resultado:
Prueba de ejecución de instancia de la clase dinámica DiccionarioDinamico
Figura 3. Prueba de ejecución de instancia de la clase dinámica DiccionarioDinamico.

5. Conclusiones

A pesar del grado de complejidad (puede ser subjetivo) del uso de DynamicObject, hemos obtenido un conocimiento básico, claro, y conciso de esta clase. En los ejemplos prácticos quedó demostrado la capacidad dinámica sobre los miembros de tipo que introduce el uso conjugado del tipo dynamic y la instanciación de una subclase DynamicObject.

Glosario

  • CLR
  • Dinámico
  • DLR

Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: DynamicObject Class (System.Dynamic) - http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject(v=vs.110).aspx
[3]: Dynamic Language Runtime Overview - http://msdn.microsoft.com/en-us/library/dd233052(v=vs.110).aspx
[4]: Propiedades en C# | OrtizOL - Experiencias Construcción Software (xCSw) http://ortizol.blogspot.com/2013/10/propiedades-en-c.html
[5]: DynamicObject.TryGetMember Method (System.Dynamic) - http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetmember(v=vs.110).aspx
[6]: Adventures with C# 4.0 dynamic - ExpandoObject, ElasticObject, and a Twitter client in 10 minutes - CodeProject - http://www.codeproject.com/Articles/62839/Adventures-with-C-dynamic-ExpandoObject-Elasti
[7]: Dictionary(TKey, TValue) Class (System.Collections.Generic) - http://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx
[8]: Tipos Genéricos en C# - Parte 8: Delegados Genéricos - http://ortizol.blogspot.com/2014/05/tipos-genericos-en-c-parte-8-delegados.html


J

jueves, 12 de junio de 2014

Receta No. 3-17 en C#: Invocación Dinámica de Miembros de un Tipo

Tabla de Contenido

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
3.1 dynamic
4. Práctica: Código Fuente C#
5. Conclusiones
6. Glosario
Literatura & Enlaces

0. Introducción

Esta receta nos presentará una alternativa a reflection a través del uso de la construcción dynamic. Conoceremos los escenarios en donde es apropiado su uso, y también, cuando debemos obviar su uso por asuntos de pérdida del rendimiento de una aplicación, y en particular, por la pérdida de la comprobación estática de tipos.

1. Problema

En la receta 1-19 (Creación de un Tipo Dinámico usando ExpandoObject) aprendimos acerca del uso de la construcción dynamic para la representación de tipos de forma dinámica, es decir, en tiempo de ejecución. Ahora que ya sabemos de su existencia en C#, queremos aplicarla para invocar miembros de un tipo de forma dinámica.

2. Solución

La solución a este requerimiento consiste en la conjugación del conocimiento y práctica adquiridos en la receta anterior (Invocar un Miembro de un Tipo con Reflection), donde aprendimos cómo invocar los miembros de un tipo usando la técnica .NET Reflection: uso del método InvokeMember (System.Type) y el método Invoke (System.Reflection.MemberInfo), y el uso de la construcción dynamic.

3. Discusión de la solución

Gracias a [1] sabemos que el uso de la construcción dynamic [3] de C# representa un enfoque alternativo a reflection, esto, para la invocación de miembros de un tipo usando el soporte con el que cuenta la versión 4.0 de .NET 4.0: DLR (Dynamic Language Runtime) [4].

Veamos en breve la definición uso de dynamic.

3.1 dynamic

Desde la versión 4.0 de .NET en C# podemos utilizar dynamic para la resolución de operaciones sobre tipos en tiempo de ejecución. Mientras que en tiempo de compilación, la comprobación de tipos, casting, boxing y unboxing, &c., son descartados por el compilador.

En este ejemplo podemos encontrar la diferencia entre la comprobación en tiempo de compilación y en tiempo de ejecución.

Archivo de código fuente PruebaDynamicObject.cs [enlace alternativo]:

En la línea 10 declaramos una variable de dynamic -dyn-, y la inicializamos con la literal entera 1;en la siguiente línea una instancia de object -obj-, con el valor entero 1 (boxing). Más adelante sobre la línea 13 sumamos 3 al valor 1 que tiene encapsulado el tipo dynamic (línea 10).

Continuando, si intentamos hacerlo mismo, es decir 

obj = ((object)obj) + 3;


El compilador de C# generará el error CS0019 [5] debido a que no es posible aplicar el operador + sobre un tipo object y una literal entera (en su lugar, era necesario hacer casting((object)obj) + 3). Notemos que esto ha ocurrido en tiempo de compilación, y por supuesto, nos genera una ventaja significativa sobre la comprobación de tipos en tiempo de ejecución. Demostrémolo a través del intento de invocar un miembro no definido sobre la variable dynamic -dyn-:

dyn.MetodoInexistente ()

La compilación del programa en el archivo de código fuente PruebaDynamicObject.cs no generará ningún error en tiempo de compilación, sin embargo, cuando intentemos ejecutar el assembly:

  1. .\PruebaDynamicObject.exe

obtendremos el siguiente mensaje de error:
Intento de invocar método inexistente en una variable dynamic
Figura 1. Intento de invocar método inexistente en una variable dynamic.
En el mensaje de error que aparece en la Figura 1 se informa que ha ocurrido la excepción RuntimeBinderException (N:Microsoft.CSharp.RuntimeBinder) [6] que se traduce en el intento de enlazar (binding) miembros de un tipo inexistentes en tiempo de ejecución.

Antes de finalizar, sobre el artículo en DotNetPerls [2, 7] nos advierten sobre el uso de dynamic:
Dynamic is advanced functionality. It can be useful. But usually it should be avoided. It erases many benefits of the C# language.
Además:
The dynamic keyword influences compilation. A dynamic variable, parameter or field can have any type. Its type can change during runtime. The downside is that performance suffers and you lose compile-time checking.
[Nota: Recomiendo la lectura de la receta Creación de un Tipo Dinámico usando ExpandoObject en donde podrán encontrar una explicación más extensa sobre este tipo .]

4. Práctica: Código Fuente C#

En este ejemplo crearemos la versión con uso de dynamic en contraste con la versión de la sección práctica de la receta 3.16 [9]:

Archivo de código fuente VersionDynamic.cs [enlace alternativo]:
Empezando la sección de código cliente (líneas 15-27), exactamente en la línea 17 declaramos la variable dynamic -dyn-. En la línea 20, asignamos a esta variable una instancia de la clase VersionDynamic. Invocamos al método ImprimirMensaje con los parámetros formales de su firma. En esta última parte debemos asegurarnos que el miembro que estamos invocando existe, y que los argumentos son aplicados tal cual como se especifican la firma (tipos y orden).

Compilación:


  1. csc /target.exe VersionDynamic.cs

Ejecución assembly:


  1. .\VersionDynamic.cs

Resultado:
Prueba ejecución de receta con uso de dynamic
Figura 2. Prueba ejecución de receta con uso de dynamic.

5. Conclusiones

Creamos una receta en la que aprendimos a invocar miembros de un tipo de forma dinámica a través del uso de la construcción dynamic (que fue introducida en la versión 4.0 de .NET Framework). En la sección práctica se demostró que invocar miembros de un tipo es mucho más simple que utilizar la técnica .NET Reflection, sin embargo, como se menciono dynamic empobrece el rendimiento de una aplicación, además de disuadir la comprobación de tipos en tiempo de compilación.

6. Glosario

  • Comprobación de tipos
  • Dinámico
  • DLR
  • Miembro de tipo
  • Reflection
  • Tiempo de compilación
  • Tiempo de ejecución

7. Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: C# Dynamic Keyword - http://www.dotnetperls.com/dynamic
[3]: dynamic (C# Reference) - http://msdn.microsoft.com/en-us/library/dd264741.aspx
[4]: Dynamic Language Runtime Overview - http://msdn.microsoft.com/en-us/library/dd233052(v=vs.110).aspx
[5]: Compiler Error CS0019 - http://msdn.microsoft.com/en-us/library/a63h61ky.aspx
[6]: RuntimeBinderException Class (Microsoft.CSharp.RuntimeBinder) - http://msdn.microsoft.com/en-us/library/microsoft.csharp.runtimebinder.runtimebinderexception(v=vs.110).aspx
[7]: C# Tutorial: Dot Net Perls - http://www.dotnetperls.com/
[8]: Receta No. 1-19 en C#: Creación de un Tipo Dinámico usando ExpandoObject | OrtizOL Experiencias Construcción Software - http://ortizol.blogspot.com/2014/02/receta-no-1-19-en-c-creacion-de-un-tipo.html
[9]: Receta No. 3-16 en C#: Invocar un Miembro de un Tipo con Reflection | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/06/receta-no-3-16-en-csharp-invocar-un-miembro-de-un-tipo-con-reflection.html


J