2010-05-02 13 views
7

Das Problem des Einzelversands ist vor allem Leuten bekannt, die mit statisch typisierten Sprachen wie Java und C# arbeiten. Die Grundidee ist:Kann der neue dynamische Datentyp "Variable" in .NET 4.0 das Problem der einzelnen/mehreren Methoden in CLR beheben?

Während der Laufzeit-Polymorphismus ermöglicht es uns, den richtigen Methodenaufruf zum Versand nach der Art (Laufzeittyp) von receiver, zum Beispiel:

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

Der Methodenaufruf durchgeführt wird, wird nach zum Laufzeittyp von mything, nämlich Cat. Dies ist die einzige Dispatch-Funktion (die in Java/C# vorhanden ist).

Nun, wenn Sie nicht nur auf dem Laufzeittyp des Empfängers müssen versenden, sondern auf die Art der (Mehrfach-) Argumente entweder, stehen Sie ein kleines Problem:

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

Die zweite Methode nie aufgerufen wird , weil wir in unserem "consumer" -Code nur dazu neigen, verschiedene Arten von Objekten (Besucher in meinem Beispiel) nach ihrem gemeinsamen Supertyp oder Interface zu behandeln.

Deshalb habe ich fragen - weil dynamische Eingabe des Polymorphismus mehrere Dispatch ermöglicht und C# 4.0 hat das dynamische Keyword;)

+5

Was ist das Problem mit dem Versand einzelner/mehrerer Methoden? –

+0

Ich werde meine Frage mit Wikipedia-Link aktualisieren) – Bubba88

+0

Huh, ist die Frage _that_ Way dumm? Oder ich vermisse gerade etwas? – Bubba88

Antwort

12

Ja, dynamische Typisierung ermöglicht mehrere Dispatch - und nein, Sie müssen nicht Ihr eigenes dynamisches Objekt erstellen, um es zu tun.

Angenommen, wir wollten Enumerable.Count() selbst implementieren, und wir wollten keine Last von "if (source is IList)" Tests in unserem Code. Wir könnten es so schreiben:

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; 
    } 
} 

Ich sage nicht, es wäre eine gute Idee sein, aber das ist, wie es funktionieren würde :)

Beachten Sie, dass Sie vorsichtig sein müssen, nicht einzuführen Situationen, in denen Sie könnten mit einem mehrdeutigen Aufruf für einige Typen enden. Dies wäre kein Problem bei der Verwendung von Klassen für Parameter, aber bedenken Sie, dass eine einzelne Klasse mehrere Schnittstellen implementieren kann.

+0

zumindest, ein schönes Beispiel für 'dynamische'. – peterchen

+0

Ja! Das war es, was ich wollte) Vielen Dank für die Erklärung und ein wenig O_o Jon Skeet zu sehen, meine Frage zu beantworten :) – Bubba88