Según tengo entendido, cada idioma puede tener su propio controlador dynamic
, de modo que se apliquen las reglas apropiadas. No estoy seguro si lo siguiente es correcto/incorrecto; pensamientos?¿Debería invocar un método basado en la interfaz que utiliza "dinámico" obedecer las reglas de resolución del método C#?
Escenario: dos interfaces (uno implementa la otra) con algunos métodos:
public interface IA {
void Bar(object o);
}
public interface IB : IA {
void Foo(object o);
}
y una implementación básica:
public class B : IB {
public void Foo(object o) { Console.WriteLine("Foo"); }
public void Bar(object o) { Console.WriteLine("Bar"); }
}
Ahora, con # C normales (sin dynamic
), podemos acceder métodos de IA
de un objetivo de tipo IB
:
IB b = new B();
var o = new { y = "z" };
b.Foo(o.y); // fine
b.Bar(o.y); // fine
Ahora vamos a añadir deliberadamente algunos dynamic
a los argumentos, lo que hace que el procesamiento de toda utilización de invocación dynamic
(como en el caso general esta resolución podría afectar a la sobrecarga, aunque no lo hará aquí):
IB b = new B();
dynamic x = new {y = "z"};
b.Foo(x.y); // fine
b.Bar(x.y); // BOOM!
que falle con el RuntimeBinderException
:
'IB' no contiene una definición para 'Bar'
Ahora, lo que dice i s completamente correcto en tanto como IB
no tiene un método Bar
. Sin embargo, como se ilustra en el primer ejemplo: bajo las reglas normales de C# se esperaría que dado que el tipo de declaración del objetivo es una interfaz (IB
), las otras interfaces conocidas para implementarse (es decir, IA
) se verifican como parte de la resolución de sobrecarga.
Entonces, ¿esto es un error? ¿O estoy malinterpretando?
+1 Interesante. Me pregunto si el DLR ofrece menos soporte para este tipo de cosas en comparación con el compilador/CLR. Supongo que el DLR es responsable del intento de resolución de la llamada. –
@ Adam, mi entendimiento es que para las llamadas basadas en la reflexión, hay un proveedor específico del idioma, precisamente para seguir las convenciones del lenguaje, es decir, 'Microsoft.CSharp.RuntimeBinder.Binder' –
¿Observas lo mismo con la herencia de clases tratando de llamar métodos de base? (A diferencia de los métodos de interfaz heredados). –