2010-05-02 13 views
7

El problema del envío único es más familiar para las personas que se dedican a la codificación con lenguajes tipados estáticos como Java y C#. La idea básica es:¿El nuevo tipo de variable "dinámica" en .NET 4.0 resuelve el problema de envío de método único/múltiple en CLR?

Mientras que el polimorfismo en tiempo de ejecución permite que enviemos a la llamada al método correcto de acuerdo con el tipo (tipo de tiempo de ejecución) de receiver, por ejemplo:

IAnimal mything = new Cat(); 
mything.chop(); 

se realizará la llamada al método de acuerdo al tipo de tiempo de ejecución mything, a saber Cat. Esta es la capacidad de envío único (que está presente en Java/C#).

Ahora, si necesita enviar no sólo en el tipo de ejecución del receptor, sino en los tipos de (múltiples) argumentos o bien, que se enfrentan a un pequeño problema:

public class MyAcceptor { 
    public void accept (IVisitor vst) {...} 
    public void accept (EnhancedConcreteVisitor vst) {...} 
} 

El segundo método nunca se llama , porque en nuestro código de "consumidor" solo tendemos a tratar diferentes tipos de objetos (visitantes en mi ejemplo) por su supertipo común o interfaz.

Es por eso que pido - tipado dinámico porque permite que el polimorfismo de despacho múltiple y C# 4.0 tiene esa palabra clave dinámica;)

+5

¿Cuál es el problema de envío único o múltiple de método? –

+0

Actualizaré mi pregunta con el enlace de la wikipedia) – Bubba88

+0

¿Eh, la pregunta es así de estúpida? ¿O solo extraño algo? – Bubba88

Respuesta

12

Sí, la tipificación dinámica permite despachos múltiples, y no, no tiene que crear su propio objeto dinámico para hacerlo.

Supongamos que queremos implementar Enumerable.Count() nosotros mismos, y no queremos una carga de pruebas "if (source is IList)" en nuestro código. Podríamos escribir así:

public static class Enumerable 
{ 
    public static int Count<T>(this IEnumerable<T> source) 
    { 
     dynamic d = source; 
     return CountImpl(d); 
    } 

    private static int CountImpl<T>(ICollection<T> collection) 
    { 
     return collection.Count; 
    } 

    private static int CountImpl(ICollection collection) 
    { 
     return collection.Count; 
    } 

    private static int CountImpl<T>(string text) 
    { 
     return text.Length; 
    } 

    private static int CountImpl<T>(IEnumerable<T> source) 
    { 
     // Fallback 
     int count = 0; 
     foreach (T t in source) 
     { 
      count++; 
     } 
     return count; 
    } 
} 

No estoy diciendo que sería una buena idea, pero eso es cómo funcionaría :)

Tenga en cuenta que hay que tener cuidado de no introducir situaciones donde podría terminar con una llamada ambigua para algunos tipos. Esto no sería un problema al usar clases para parámetros, pero considera que una sola clase puede implementar múltiples interfaces.

+0

como mínimo, un buen ejemplo para 'dynamic'. – peterchen

+0

¡Sip! Eso es lo que buscaba. Muchas gracias por la explicación y un poco de O_o para ver a Jon Skeet responder mi pregunta :) – Bubba88

Cuestiones relacionadas