Las conjeturas de Tomás son bastante buenas. Su razonamiento sobre los métodos de extensión es perfecto. Básicamente, para hacer que los métodos de extensión funcionen necesitamos que el sitio de llamadas en tiempo de ejecución sepa de alguna manera qué instrucciones de uso estaban en vigor en el momento de la compilación.Simplemente no tuvimos suficiente tiempo ni presupuesto para desarrollar un sistema por el cual esta información pudiera persistir en el sitio de llamadas.
Para lambdas, la situación es en realidad más compleja que el simple problema de determinar si la lambda va a árbol de expresión o delegar. Tenga en cuenta lo siguiente:
d.M(123)
donde d es una expresión de tipo dinámico. * ¿Qué objeto debería pasar en el tiempo de ejecución como argumento para el sitio de llamada "M"? Claramente, colocamos 123 y lo pasamos. Luego, el algoritmo de resolución de sobrecarga en el enlazador de tiempo de ejecución mira el tipo de tiempo de ejecución de dy el tipo de tiempo de compilación de int 123 y funciona con eso.
Ahora ¿Y si era
d.M(x=>x.Foo())
Ahora qué objeto debemos pasar como argumento? No tenemos forma de representar el "método lambda de una variable que llama a una función desconocida llamada Foo en lo que sea que sea el tipo de x".
Supongamos que queremos implementar esta característica: ¿qué tendríamos que implementar? En primer lugar, necesitaríamos una forma de representar un sin vinculación lambda. Los árboles de expresión son por diseño solo para representar lambdas, donde se conocen todos los tipos y métodos. Tendríamos que inventar un nuevo tipo de árbol de expresiones "sin tipo". Y luego tendríamos que implementar todos de las reglas para el enlace lambda en el enlace de tiempo de ejecución.
Considera ese último punto. Lambdas puede contener declaraciones. La implementación de esta función requiere que el archivo de tiempo de ejecución contenga todo el analizador semántico para cada posible declaración en C#.
Eso fue en órdenes de magnitud fuera de nuestro presupuesto. Todavía estaríamos trabajando en C# 4 hoy si hubiéramos querido implementar esa característica.
Desafortunadamente, esto significa que LINQ no funciona muy bien con la dinámica, porque LINQ por supuesto usa lambdas sin tipo en todo el lugar. Es de esperar que en alguna versión futura hipotética de C# tengamos un encuadernador de tiempo de ejecución más completo y la capacidad de hacer representaciones homoicónicas de lambdas independientes. Pero no aguantaría la respiración esperando si fuera tú.
ACTUALIZACIÓN: Un comentario solicita una aclaración sobre el punto sobre el analizador semántico.
considerar las siguientes sobrecargas:
class C {
public void M(Func<IDisposable, int> f) { ... }
public void M(Func<int, int> f) { ... }
...
}
y una llamada
d.M(x=> { using(x) { return 123; } });
Supongamos que D es del tipo de compilación de tiempo C. dinámica y tipo de ejecución ¿Qué debe hacer el aglutinante de tiempo de ejecución?
El aglutinante tiempo de ejecución debe determinar en tiempo de ejecución si la expresión x=>{...}
es convertible a cada uno de los tipos de delegado en cada una de las sobrecargas de M.
Con el fin de hacer que, el ligante de tiempo de ejecución debe ser capaz de determinar que la segunda sobrecarga no es aplicable.Si fuera aplicable, entonces podría tener un int como argumento para una instrucción using, pero el argumento para una instrucción using debe ser desechable. Esto significa que la carpeta de tiempo de ejecución debe conocer todas las reglas para la instrucción using y poder informar correctamente si un posible uso de la instrucción using es legal o ilegal.
Está claro que no está restringido a la instrucción using. El encuadernador de tiempo de ejecución debe conocer todas las reglas para C# para determinar si una declaración determinada lambda es convertible a un tipo de delegado determinado.
No tuvimos tiempo para escribir una carpeta de tiempo de ejecución que era esencialmente un compilador de C# completamente nuevo que genera árboles DLR en lugar de IL. Al no permitir lambdas, solo tenemos que escribir un encuadernador de tiempo de ejecución que sepa cómo enlazar llamadas a métodos, expresiones aritméticas y algunos otros tipos simples de sitios de llamadas. Permitir lambdas hace que el problema del enlace en tiempo de ejecución sea del orden de docenas o cientos de veces más costoso de implementar, probar y mantener.
Eso es obvio, un objeto dinámico no tiene una propiedad llamada 'Método' y no es un' IEnumarable'. No veo esas cosas que mencionas como limitaciones, tal vez tú y el autor no entendieron lo que 'dinámico 'hace. – BrunoLM
No lo creo. La validez de los miembros (como "Método") no será verificada por el compilador. –