Verwenden von dynamischen Typen

Beim Typ dynamic handelt es sich um einen statischen Typ, doch ein Objekt des Typs dynamic umgeht die Überprüfung statischer Typen. In den meisten Fällen entspricht es der Funktionsweise des Typs object. Der Compiler geht davon aus, dass ein dynamic-Element jeden Vorgang unterstützt. Daher müssen Sie nicht ermitteln, ob das Objekt seinen Wert von einer COM-API, einer dynamischen Sprache wie IronPython, vom HTML-DOM (Document Object Model), aus der Reflexion oder von einer anderen Quelle im Programm erhält. Wenn der Code jedoch ungültig ist, treten zur Laufzeit Fehler auf.

Wenn z. B. die exampleMethod1-Instanzmethode im folgenden Code nur einen Parameter hat, erkennt der Compiler, dass der erste Aufruf der ec.exampleMethod1(10, 4)-Methode ungültig ist, da er zwei Argumente enthält. Dieser Aufruf löst einen Compilerfehler aus. Der zweite Aufruf der dynamic_ec.exampleMethod1(10, 4)-Methode wird vom Compiler nicht überprüft, da der Typ von dynamic_ecdynamic ist. Daher wird kein Compilerfehler gemeldet. Allerdings bleibt der Fehler nicht unbegrenzt unbemerkt. Er tritt zur Laufzeit auf und löst eine Laufzeitausnahme aus.

static void Main(string[] args)
{
    ExampleClass ec = new ExampleClass();
    // The following call to exampleMethod1 causes a compiler error
    // if exampleMethod1 has only one parameter. Uncomment the line
    // to see the error.
    //ec.exampleMethod1(10, 4);

    dynamic dynamic_ec = new ExampleClass();
    // The following line is not identified as an error by the
    // compiler, but it causes a run-time exception.
    dynamic_ec.exampleMethod1(10, 4);

    // The following calls also do not cause compiler errors, whether
    // appropriate methods exist or not.
    dynamic_ec.someMethod("some argument", 7, null);
    dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
    public ExampleClass() { }
    public ExampleClass(int v) { }

    public void exampleMethod1(int i) { }

    public void exampleMethod2(string str) { }
}

In diesen Beispielen ist es die Aufgabe des Compilers, Informationen darüber zusammenzustellen, was jede Anweisung für die Behandlung des dynamic-Objekts oder des Ausdrucks vorschlägt. Die Runtime untersucht die gespeicherten Informationen, und jede ungültige Anweisung löst eine Laufzeitausnahme aus.

Das Ergebnis der meisten dynamischen Vorgänge ist wiederum dynamic. Wenn Sie z.B. den Mauszeiger im folgenden Beispiel auf die Verwendung von testSum halten, zeigt IntelliSense den Typ (local variable) dynamic testSum an.

dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);

Vorgänge, in denen das Ergebnis nicht dynamic lautet, sind z. B.:

  • Konvertierungen von dynamic in einen anderen Typ
  • Konstruktoraufrufe, die Argumente des Typs dynamic enthalten

In der folgenden Deklaration ist der Typ von testInstance z.B. ExampleClass, nicht dynamic:

var testInstance = new ExampleClass(d);

Konvertierungen

Konvertierungen zwischen dynamischen Objekten und anderen Typen sind sehr einfach. Durch Konvertierungen können Entwickler*innen zwischen dynamischem und nicht dynamischem Verhalten wechseln.

Sie können alles implizit in dynamic konvertieren, wie in den folgenden Beispielen gezeigt.

dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();

Umgekehrt können Sie jede implizite Konvertierung dynamisch auf jeden Ausdruck vom Typ dynamic anwenden.

int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;

Überladungsauflösung mit Argumenten vom Typ „dynamic“

Überladungsauflösung erfolgt zur Laufzeit anstatt zur Kompilierzeit, wenn eines oder mehrere der Argumente in einem Methodenaufruf vom Typ dynamic sind, oder wenn der Empfänger des Methodenaufrufs vom Typ dynamic ist. Im folgenden Beispiel wird durch das Senden von d1 als Argument kein Compilerfehler ausgelöst, wenn die einzige zugängliche exampleMethod2-Methode ein Zeichenfolgenargument akzeptiert. Allerdings wird eine Laufzeitausnahme ausgelöst. Die Überladungsauflösung schlägt zur Laufzeit fehl, da der Laufzeittyp von d1int ist und exampleMethod2 eine Zeichenfolge benötigt.

// Valid.
ec.exampleMethod2("a string");

// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);

Dynamic Language Runtime (DLR)

Die DLR (Dynamic Language Runtime) bietet die Infrastruktur, die den Typ dynamic in C# und die Implementierung von dynamischen Programmiersprachen wie IronPython und IronRuby unterstützt. Weitere Informationen zur DLR finden Sie unter Übersicht über die Dynamic Language Runtime.

COM-Interop

Viele COM-Methoden ermöglichen die Variation von Argument- und Rückgabetypen durch Festlegen der Typen als object. COM-Interop erfordert das explizite Umwandeln der Werte für die Koordination mit stark typisierten Variablen in C#. Wenn Sie mit der Option EmbedInteropTypes (C#-Compileroptionen) kompilieren, ermöglicht Ihnen die Einführung des Typs dynamic, die Vorkommen von object in COM-Signaturen so zu behandeln, als wären sie vom Typ dynamic. Dadurch können Sie einen Großteil der Umwandlung vermeiden. Weitere Informationen zur Verwendung des Typs dynamic mit COM-Objekten finden Sie im Artikel Zugreifen auf Office-Interop-Objekte mithilfe von C#-Features.

Titel Beschreibung
dynamic Beschreibt die Verwendung des Schlüsselworts dynamic.
Übersicht über die Dynamic Language Runtime Bietet eine Übersicht über die Dynamic Language Runtime (DLR), eine Laufzeitumgebung, die der Common Language Runtime (CLR) eine Reihe von Diensten für dynamische Sprachen hinzufügt.
Exemplarische Vorgehensweise: Erstellen und Verwenden von dynamischen Objekten Bietet eine ausführliche Anleitung zum Erstellen eines benutzerdefinierten dynamischen Objekts und zum Erstellen eines Projekts, das auf eine IronPython-Bibliothek zugreift.