Verwenden des Typs dynamic (C#-Programmierhandbuch)

Visual C# 2010 führt einen neuen Typ ein, dynamic. Bei diesem Typ handelt es sich um einen statischen Typ. Ein Objekt des Typs dynamic umgeht aber die Überprüfung statischer Typen. In den meisten Fällen entspricht es der Funktionsweise des Typs object. Bei einem Element, das zur Kompilierzeit als dynamic typisiert wird, wird davon ausgegangen, dass es alle Vorgänge unterstützt. Daher müssen Sie sich keine Gedanken darüber machen, ob das Objekt seinen Wert von einer COM-API, einer dynamischen Sprache wie IronPython, vom HTML-DOM (Document Object Model), aus der Reflektion oder von einer anderen Quelle im Programm erhält. Wenn der Code jedoch nicht gültig ist, werden Fehler zur Laufzeit abgefangen.

Wenn z.B. die Instanzmethode exampleMethod1 im folgenden Code nur einen Parameter hat, erkennt der Compiler, dass der erste Aufruf der Methode, ec.exampleMethod1(10, 4), nicht gültig ist, da er zwei Argumente enthält. Dieser Aufruf löst einen Compilerfehler aus. Der zweite Aufruf der Methode, dynamic_ec.exampleMethod1(10, 4), 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 wird zur Laufzeit abgefangen und führt zu einer Laufzeitausnahme.

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 Rolle des Compilers, Informationen darüber zusammenzustellen, was jede Anweisung für die Behandlung des Objekts oder des Ausdrucks vorschlägt, die als dynamic typisiert sind. Die gespeicherten Informationen werden zur Laufzeit überprüft, und jede ungültige Anweisung verursacht eine Laufzeitausnahme.

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 ist, enthalten Konvertierungen von dynamic in einen anderen Typ, und Konstruktoraufrufe, die Argumente vom Typ dynamic enthalten. In der folgende Deklaration ist der Typ von testInstance z.B. ExampleClass, nicht dynamic.

var testInstance = new ExampleClass(d);

Im folgenden Abschnitt „Konvertierungen“ finden Sie Konvertierungsbeispiele.

Konvertierungen

Konvertierungen zwischen dynamischen Objekten und anderen Typen sind sehr einfach. Dadurch kann der Entwickler zwischen dynamischem und nicht dynamischem Verhalten wechseln.

Jedes Objekt kann implizit zu einem dynamischen Typ konvertiert werden, 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 kann eine implizite Konvertierung dynamisch auf einen Ausdruck vom Typ dynamic angewendet werden.

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 so definiert wird, dass sie 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

Die Dynamic Language Runtime (DLR) ist eine neue API in .NET Framework 4. Sie 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

Visual C# 2010 enthält mehrere Funktionen, die die Benutzerfreundlichkeit bei Interoperationen mit COM-APIs wie den Automatisierungs-APIs in Microsoft Office verbessern. Zu diesen Verbesserungen gehören die Verwendung des Typs dynamic und von benannten und optionalen Argumenten.

Viele COM-Methoden ermöglichen die Variation von Argument- und Rückgabetypen durch Festlegen der Typen als object. Dadurch wird das explizite Umwandeln der Werte für die Koordination mit stark typisierten Variablen in C# notwendig. Wenn Sie mit der Option /link (C#-Compileroptionen) kompilieren, ermöglicht es Ihnen die Einführung des Typs dynamic, das Vorkommen von object in COM-Signaturen so zu behandeln, als wäre es vom Typ dynamic. Dadurch können Sie einen Großteil der Umwandlung umgehen. Die folgenden Anweisungen unterscheiden z.B., wie Sie auf eine Zelle in einem Arbeitsblatt von Microsoft Office Excel mit dem Typ dynamic und ohne den Typ dynamic zugreifen.

// Before the introduction of dynamic.
((Excel.Range)excelApp.Cells[1, 1]).Value2 = "Name";
Excel.Range range2008 = (Excel.Range)excelApp.Cells[1, 1];
// After the introduction of dynamic, the access to the Value property and
// the conversion to Excel.Range are handled by the run-time COM binder.
excelApp.Cells[1, 1].Value = "Name";
Excel.Range range2010 = excelApp.Cells[1, 1];
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.
Gewusst wie: Zugreifen auf Office-Interop-Objekte mithilfe von Visual C#-Funktionen Veranschaulicht, wie Sie ein Projekt erstellen, das benannte und optionale Argumente, den Typ dynamic und andere Verbesserungen verwendet, die den Zugriff auf Office-API-Objekte vereinfachen.