2010-02-13 18 views
59

Creo que tengo mi cerebro medio envuelto en el concepto de Tipos dinámicos en C# 4, pero no puedo imaginar un escenario en el que realmente quisiera usarloC# 4: Ejemplo en el mundo real de tipos dinámicos

Estoy seguro de que hay muchos, pero sólo estoy teniendo problemas para hacer la conexión en cuanto a cómo podría diseñar una solución que se resuelve con una mejor dinámica en lugar de interfaces, la inyección de dependencia, etc.

Entonces, ¿cuál es un escenario de aplicación en el mundo real donde el uso de tipos dinámicos es apropiado?

+2

Ver: http://stackoverflow.com/questions/253460/what-is- the-practical-use-of-dynamic-variable-in-c-4-0 –

+5

Aparte de los objetos COM, estoy firmemente de la opinión de que no son particularmente útiles en C# /. NET, y una mejor solución casi siempre existe ... – Noldorin

+3

Ah, y la interoperabilidad con lenguajes dinámicos como IronPython por supuesto. Es puro C#, no tiene lugar, sin embargo. – Noldorin

Respuesta

62

Hay un montón de casos en la que son ya usando tipado dinámico y dinámico vinculante hoy. Simplemente no te das cuenta, porque todo está oculto detrás de cadenas o System.Object, ya que hasta C# 4, el soporte necesario no estaba allí.

Un ejemplo es la interoperabilidad COM: COM es en realidad un sistema de objetos semidinámico. Cuando se hace interoperabilidad COM, muchos métodos realmente devuelven un objeto dinámico, pero debido a que C# no los admite, se devolvieron como System.Object y tuvo que realizarlos usted mismo, posiblemente detectando excepciones en el camino.

Otro ejemplo es interactuar con datos tipeados dinámicamente (o incluso sin tipo), como JSON, CSV, HTML, schemaless XML, servicios web sin esquema, bases de datos sin esquema (que son, después de todo, el nuevo hotness). Hoy, usas cadenas para aquellos.Una API XML se vería como

var doc = new XmlDocument("/path/to/file.xml"); 
var baz = doc.GetElement("foo").GetElement("qux"); 

y así sucesivamente. Pero ¿qué tal:

dynamic doc = new XmlDocument("/path/to/file.xml"); 
var baz = doc.foo.qux; 

¿No parece agradable?

Un tercer ejemplo es la reflexión. Hoy, la invocación de un método a través de la reflexión se hace pasando una cadena al InvokeMember (o lo que sea que se llame). ¿No sería más agradable, ya sabes, solo invocar la maldita cosa?

Luego, hay generación de datos dinámicos (básicamente lo opuesto al segundo ejemplo). He aquí un ejemplo de cómo generar algo de XML dinámico:

dynamic doc = new XmlBuilder(); 
doc.articles(id=42, type="List",() => { 
    article(() => { 
    number(42); 
    title("blahblubb");});}); 

Esto no es tan hermoso como el rubí equivalente, pero es lo mejor que podía llegar a en tan poco tiempo :-)

Y por último pero ciertamente no menos importante, la integración con un lenguaje de tipado dinámico. Ya sea que se trate de JavaScript en una aplicación de Silverlight, un motor de reglas personalizado incrustado en su aplicación comercial o una instancia de DLR que usted aloja en su programa CAD/IDE/editor de texto.

+1

Hmm ... interesante, pero no puedo conseguir que estos ejemplos funcionen en C# 4.0. ¿Estoy haciendo algo mal? – devuxer

+0

@DanM: para que funcionen estos ejemplos hipotéticos, obviamente tendrá que implementar las API hipotéticas primero, es decir, debe * escribir * las clases 'XmlDocument' y' XmlBuilder' que son compatibles con esta API. El último debería ser bastante obvio, creo. –

+0

Ahh, ya veo. (Lo que me confundió es que 'XmlDocument' ya es una clase en el framework .NET.) – devuxer

3

Hay un ejemplo en MSDN:

Muchos métodos COM permiten la variación en los tipos de argumentos y tipo de retorno mediante la designación de los tipos como objeto. Esto ha necesitado el lanzamiento explícito de los valores para coordinar con las variables fuertemente tipadas en C#. Si compila usando la opción/link (Opciones del compilador C#), la introducción del tipo dinámico le permite tratar las ocurrencias del objeto en las firmas COM como si fueran de tipo dinámico, y así evitar gran parte del lanzamiento.

Otro ejemplo es si tiene que interoperar con lenguajes dinámicos.

También hay ocasiones en las que desea hacer que un código sea genérico pero no puede hacerlo porque aunque los objetos implementen el mismo método, no comparten una clase base o interfaz adecuada que declare los métodos que necesita. Un ejemplo de esto es tratar de hacer algo genérico con enteros y cortos. Es un poco complicado, pero dinámico te permite llamar a los mismos métodos en estos diferentes tipos, lo que permite una mayor reutilización del código.

Actualización: Un poco de búsqueda aquí encontró this related post.

1

Leí un artículo interesante sobre esto (adjunto) por Scott Hanselman. Señala que, a diferencia del uso de objetos, puede usar métodos dinámicos para referenciar desde objetos COM más antiguos, donde el compilador no sabe que existe un método. Encontré el enlace útil.

Scott Hanselman - C#4 and the dynamic keyword

2

Creo que otros han dado excelentes respuestas hasta ahora, así que solo quiero agregar este ejemplo de David Hanson. Hist post muestra la aplicación más práctica que he encontrado hasta ahora para los tipos dinámicos en C# donde los usa para crear objetos proxy. En este ejemplo, crea un proxy que permite elevar excepciones en los errores de enlace de WPF. No estoy seguro de si esto también podría lograrse en el caso de los enlaces WPF utilizando CustomTypeDescriptors y los conceptos de descriptores de propiedades en general, pero independientemente del uso del nuevo tipo dinámico C# 4.0 es una gran demostración de sus capacidades.

Raising binding exceptions in WPF & Silverlight with .net 4.0 Dynamics

métodos

Otro uso que se me ocurre para este tipo de dinámicas es crear proxies que de igual forma se pueden enchufar como DataContext en WPF o en otros lugares donde se espera un tipo de objeto genérico y de reflexión son normalmente utilizado para interrogar el tipo. En estos casos, especialmente cuando se construyen pruebas, se puede usar un tipo dinámico que permita que los accesores de propiedad sean llamados y registrados en consecuencia por el objeto proxy de una manera dinámica sin tener que codificar propiedades en una clase de solo prueba.

Cuestiones relacionadas