El código siguiente muestra mi pregunta:conversión explícita del valor de retorno método dinámico dentro de un método no permite un método de extensión que se llamará
public class DynamicExample
{
public void DoSomething()
{
var x = new ExpandoObject();
dynamic d = x;
d.GetString = (Func<string>)(() => "Some Value");
d.GetString().SomeStringExtension(); // Doesn't work - expected
((string)d.GetString()).SomeStringExtension(); // Works - expected
Build(d).SomeStringExtension(); // Doesn't work - unexpected?
}
private static string Build(dynamic d)
{
return (string)d.GetString();
}
}
public static class StringExtensions
{
public static int SomeStringExtension(this string s)
{
return s.Length;
}
}
La pregunta es, ¿por qué hay una diferencia entre el compilador ¿Lanzando el tipo en línea a la llamada del método de extensión y moviendo ese lanzamiento en un método separado?
+1 Como una pregunta adicional: ¿por qué en 'var s = Build (d);' the 'var' es dinámico? (Añadiré que esta es, probablemente, la verdadera pregunta. Si el resultado de 'Build (d)' es implícitamente dinámico, entonces la resolución de 'SomeStringExtension' no se puede hacer en tiempo de ejecución) – xanatos
No funciona porque 'dynamic' le está diciendo al compilador que deje de hacer análisis de tipo en la variable. ¿Cómo espera que coincida con los métodos de extensión sin esa información? El molde explicado funciona porque tu conversión explícita a un tipo de tiempo de compilación conocido. – asawyer
De acuerdo. Sospecho que el compilador está decidiendo que todo el método Build (dynamic d) debe estar sujeto a enlaces dinámicos, pero no entiendo el motivo. (Se va a editar la pregunta para deshacerse de los múltiples métodos de compilación, de forma tal que los comentarios sean válidos) –