2009-08-18 22 views
21

C# 4 contendrá una nueva palabra clave dynamic que traerá funciones de lenguaje dinámico a C#.¿Cómo usarás el tipo dinámico C# 4?

¿Cómo planeas usarlo en tu propio código, qué patrón propones? ¿En qué parte de su proyecto actual hará que su código sea más limpio o más simple, o habilite cosas que simplemente no podría hacer (fuera de la interoperabilidad obvia con lenguajes dinámicos como IronRuby o IronPython)?

PD: Por favor, si no te gusta este C# 4 además, evita hinchar los comentarios negativamente.

Editar: reorientando la cuestión.

Los usos clásicos de dynamic son bien conocidos por la mayoría de los usuarios de stackoverflow C#. Lo que quiero saber es si piensas en nuevos patrones específicos de C# donde la dinámica puede aprovecharse de manera útil sin perder demasiado espíritu de C#.

+0

¿Pregunta duplicada? Ver http://stackoverflow.com/questions/244302/what-do-you-think-of-the-new-c-4-0-dynamic-keyword – Lazarus

+0

no realmente ... la pregunta no es '¿te gusta? eso ?' pero ¿qué vas a hacer con eso? Pero es cierto, es bastante cercano. Hice una búsqueda sobre una pregunta similar, pero no tropecé con esta. – thinkbeforecoding

+3

Esta es una discusión sin respuesta "correcta". Por lo tanto, debe ser una wiki comunitaria. – ryeguy

Respuesta

1

Lo usaré para simplificar mi código que trata con COM/Interop donde antes tenía que especificar el miembro para invocar, sus parámetros etc. (básicamente donde el compilador no sabía sobre la existencia de una función y yo necesario para describirlo en tiempo de compilación). Con la dinámica esto se vuelve menos engorroso y el código se vuelve más ágil.

+0

Excelente entrada de blog y código que simplificará mucho la interoperabilidad se puede encontrar aquí: http://tirania.org/blog/archive/2009/Aug-11.html – Yakeen

12

Dondequiera que se use la reflexión a la antigua y la legibilidad del código se haya visto afectada. Y, como dices, algunos escenarios de Interop (de vez en cuando trabajo con COM).

Eso es todo. Si se puede evitar el uso de dynamic, se debe evitar. Recopilación de tiempo de compilación, rendimiento, etc.

Hace unas semanas, recordé this article. Cuando lo leí por primera vez, fui francamente deslumbrado. Pero lo que no me había dado cuenta es que no sabía cómo incluso usar un operador de algún tipo desconocido. Empecé a preguntarme cuál sería el código generado para algo como esto:

dynamic c = 10; 
int b = c * c; 

Utilizando la reflexión regular, no puede usar los operadores definidos. Se generó bastante código, usando algunas cosas de un espacio de nombre Microsoft. Digamos que el código anterior es mucho más fácil de leer :) Es bueno que funcione, pero también fue muy lento: aproximadamente 10,000 veces más lento que una multiplicación regular (doh), y aproximadamente 100 veces más lento que una interfaz ICalculator con un método Multiply.

Editar - código generado, para los interesados:

if (<Test>o__SiteContainer0.<>p__Sitea == null) 
    <Test>o__SiteContainer0.<>p__Sitea = 
    CallSite<Func<CallSite, object, object, object>>.Create(
     new CSharpBinaryOperationBinder(ExpressionType.Multiply, 
     false, false, new CSharpArgumentInfo[] { 
      new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null), 
      new CSharpArgumentInfo(CSharpArgumentInfoFlags.None, null) })); 
b = <Test>o__SiteContainer0.<>p__Site9.Target(
     <Test>o__SiteContainer0.<>p__Site9, 
     <Test>o__SiteContainer0.<>p__Sitea.Target(
     <Test>o__SiteContainer0.<>p__Sitea, c, c)); 
+0

Creo que en casos en los que el uso de la reflexión puede ser reemplazado por dinámicos código, puede dar una muestra? – thinkbeforecoding

+0

@Think: podría usarse en casos donde las funciones se invocan de manera reflexiva, no donde se usa el reflejo para eludir el acceso (a menos que, supongo, lo lances a un objeto primero? No estoy seguro ...) o para hacer una inspección . –

7

La dinámica de palabras clave tiene que ver con la simplificación del código necesario para dos escenarios:

  • C# para interoperabilidad COM
  • C# a lenguaje dinámico (JavaScript, etc.) interop

Si bien podría ser utilizado fuera de esos escenarios, probablemente no debería ser.

+0

¿Tiene más información sobre su segundo punto, por favor, scott? un motor de juegos administrado por C# - exponer a un motor de gráficos AJAX es algo en lo que estoy trabajando y me encantaría ver cómo esto ayudaría. – divinci

4

Miguel de Icaza presenta un caso de uso muy fresco en su blog, here (fuente incluida):

dynamic d = new PInvoke ("libc"); 
d.printf ("I have been clicked %d times", times); 

Si es posible hacer esto de una manera segura y fiable, sería impresionante para nativo código de interoperabilidad

3

Esto también nos permitirá evitar tener que utilizar el patrón de visitantes en ciertos casos como multi-Dispatch ahora será posible

public class MySpecialFunctions 
{ 
    public void Execute(int x) {...} 
    public void Execute(string x) {...} 
    public void Execute(long x) {...} 
} 

dynamic x = getx(); 
var myFunc = new MySpecialFunctions(); 
myFunc.Execute(x); 

... llamará al método mejor partido en tiempo de ejecución, en lugar de estar resuelto en tiempo de compilación

+0

Por favor, ayúdame a entender la ventaja aquí. ¿Por qué no quieres que esto se resuelva en tiempo de compilación? – Jake

+0

A veces no sabe con qué tipo está trabajando, por ejemplo, está trabajando con una clase base pero necesita un comportamiento especial para los subtipos. Al atravesar una estructura de árbol, cada nodo puede heredar de un nodo de clase base, pero al procesar el nodo necesita un comportamiento específico para subtipos (es decir, nodo compuesto). Puede utilizar una clase como MySpecialFunctions y ejecutar Execute sin grandes bloques de switch/if tratando de averiguar qué método llamar comprobando el tipo de nodo que se está procesando. El código del cliente no tiene que conocer todos los subtipos para utilizar MySpecialFunctions correctamente – saret

+0

También los subtipos nuevos/alternativos de MySpecialFunctions no requerirían cambios a los nodos de proceso del código del cliente. – saret

5

Recientemente publiqué blogs sobre tipos dinámicos en C# 4.0 y, entre otros, mencioné algunos de sus posibles usos, así como algunas de sus dificultades. El artículo en sí es demasiado grande para caber aquí, pero puedes leerlo en su totalidad en este address.

A modo de resumen, aquí hay algunos casos útiles de uso (excepto la obvia de interoping con bibliotecas COM y lenguajes dinámicos como IronPython):

  • la lectura de un XML azar o JSON en un C# objeto dinámico. .Net framework contiene clases y atributos para deserializar fácilmente documentos XML y JSON en objetos C#, pero solo si su estructura es estática. Si son dinámicos y necesita descubrir sus campos en tiempo de ejecución, solo pueden deserializarse en objetos dinámicos. .Net no ofrece esta funcionalidad de forma predeterminada, pero puede hacerlo con herramientas de terceros como jsonfx o DynamicJson
  • devolver tipos anónimos de métodos. Los tipos anónimos tienen su alcance restringido al método donde están definidos, pero que se pueden superar con la ayuda de la dinámica. Por supuesto, esto es algo peligroso de hacer, ya que expondrá objetos con una estructura dinámica (sin comprobación de tiempo de compilación), pero podría ser útil en algunos casos. Por ejemplo, el siguiente método lee sólo dos columnas de una tabla de base de datos utilizando LINQ a SQL y devuelve el resultado:

    public static List<dynamic> GetEmployees() 
    { 
        List<Employee> source = GenerateEmployeeCollection(); 
        var queyResult = from employee in source 
           where employee.Age > 20 
           select new { employee.FirstName, employee.Age }; 
    
        return queyResult.ToList<dynamic>(); 
    } 
    
  • crear servicios WCF REST que devuelve datos dinámicos. Eso podría ser útil en la siguiente situación. Considere que tiene un método web que devuelve datos relacionados con el usuario. Sin embargo, su servicio expone una gran cantidad de información sobre los usuarios y no será eficiente simplemente devolverlos todos en todo momento. Sería mejor si sería capaz de permitir a los consumidores para especificar los campos que realmente necesitan, como con la siguiente URL

    http://api.example.com/users?userId=xxxx&fields=firstName,lastName,age 
    

    El problema entonces viene del hecho de que WCF sólo devolverá a los clientes respuestas hechas de objetos serializados. Si los objetos son estáticos, entonces no habría forma de devolver las respuestas dinámicas, por lo que los tipos dinámicos deben ser utilizados. Sin embargo, hay un último problema aquí y es que, por defecto, los tipos dinámicos no son serializables. En el article hay un ejemplo de código que muestra cómo superar esto (de nuevo, no lo estoy publicando aquí debido a su tamaño).

Al final, es posible que observe que dos de los casos de uso que he mencionado requieren algunas soluciones provisionales o de terceros. Esto me hace pensar que, si bien el equipo de .Net ha agregado una función muy interesante al framework, es posible que solo lo hayan agregado con COMop y la interoperabilidad de lenguajes dinámicos en mente.Sería una pena porque los lenguajes dinámicos tienen algunas ventajas importantes y proporcionarlos en una plataforma que los combine con las fortalezas de los lenguajes fuertes mecanografiados probablemente coloque a .Net y C# por delante de las demás plataformas de desarrollo.

Cuestiones relacionadas