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_ec
dynamic
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 d1
int
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.
Verwandte Artikel
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. |