2012-03-10 17 views
25

En C#, ¿alguien sabe por qué no puedo hacer lo siguiente? (Específicamente la línea marcada 'NO bien!' A continuación)¿Por qué falla el enlace dinámico cuando se usa la herencia de la interfaz?

interface A 
{ 
    void Add(dynamic entity); 
} 

interface B : A {} 

class C : B 
{ 
    public void Add(dynamic entity) 
    { 
     System.Console.WriteLine(entity); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     B b = new C(); 
     dynamic x = 23; 
     b.Add(23);  // fine 
     b.Add((int)x); // fine 
     (b as A).Add(x); // fine 
     //b.Add(x);  // NOT fine! 
    } 
} 

tengo absolutamente ningún problema si no está vinculado dinámicamente la llamada, o si yo echo de forma explícita a la interfaz en la raíz de la jerarquía, pero la llamada con destino dinámicamente me da:

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: No overload for method 'Add' takes '1' arguments 
    at CallSite.Target(Closure , CallSite , B , Object) 
    at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1) 
    at Program.Main(String[] args) in C:\Users\Stuart\Documents\Visual Studio 2010\Projects\CSharp Testbed\Program.cs:line 218 
+1

Por cierto, la última llamada falla, incluso sin una herencia de diamante. –

+0

@YuriyGuts: tanto para un ejemplo compilable mínimo eh? :) Ok, simplificando la pregunta en ese caso. –

+1

+1 - También podría ser bueno tener en cuenta que 'b.Add ((int) x)' funciona. –

Respuesta

0

parece que las múltiples capas de la herencia de interfaces están haciendo en el paso de una variable de tipo dinámico. Definitivamente está tropezando con el enlace de tiempo de ejecución.

En este punto, si usted está mirando para conseguir que funcione una posible solución es:

dynamic x = 23; 
b.Add((object)x); 

dynamic y = "Hello, World!"; 
b.Add((object)y); 

Desde dinámico es visto como objeto por el IL, por lo que todo lo fundición explícitamente el tipo de objeto conseguir que esto trabajo para ti.

+0

Para el código intermedio, el tipo dinámico realmente se ve como un tipo de objeto. Por lo tanto, para este caso, al menos, eche la dinámica como objeto de tipo porque los dos son funcionalmente equivalentes para lo que el OP intenta hacer. –

+3

La pregunta no es cómo hacer que funcione, la pregunta es ¿por qué no funciona? –

+0

@oleksii: Aunque al principio me sorprendió, parece que realmente funciona (incluso cuando cambio 'C.Add' para hacer algo más interesante con' entity'). Tengo entendido que el lanzamiento a 'objeto' obliga a que el enlace se realice en tiempo de compilación, pero que dentro de la función 'entidad' todavía se tipea dinámicamente. Así que esta es otra forma de hacer que la llamada esté ligada estáticamente -> el caso por el que dije "No tengo absolutamente ningún problema". Desafortunadamente, todavía no explica por qué tengo problemas en el caso de vinculación dinámica. –

Cuestiones relacionadas