Suche…


Bemerkungen

Das dynamic Schlüsselwort deklariert eine Variable, deren Typ zur Kompilierzeit nicht bekannt ist. Eine dynamic Variable kann einen beliebigen Wert enthalten, und der Typ des Werts kann sich zur Laufzeit ändern.

Wie in dem Buch "Metaprogrammierung in .NET" erwähnt, hat C # keinen Hintergrundtyp für das dynamic Schlüsselwort:

Die durch das Schlüsselwort dynamic aktivierte Funktionalität ist eine clevere Gruppe von Compileraktionen, die CallSite Objekte im Site-Container des lokalen Ausführungsbereichs ausgeben und verwenden. Der Compiler verwaltet, was Programmierer über diese CallSite Instanzen als dynamische Objektreferenzen CallSite . Die Parameter, Rückgabetypen, Felder und Eigenschaften, die zur Kompilierzeit dynamisch behandelt werden, sind möglicherweise mit einigen Metadaten gekennzeichnet, um anzuzeigen, dass sie für die dynamische Verwendung generiert wurden. Der zugrunde liegende Datentyp für sie ist immer System.Object .

Dynamische Variable erstellen

dynamic foo = 123;
Console.WriteLine(foo + 234);
// 357    Console.WriteLine(foo.ToUpper())
// RuntimeBinderException, since int doesn't have a ToUpper method

foo = "123";
Console.WriteLine(foo + 234);
// 123234
Console.WriteLine(foo.ToUpper()):
// NOW A STRING

Dynamisch zurückkehren

using System;

public static void Main()
{
    var value = GetValue();
    Console.WriteLine(value);
    // dynamics are useful!
}

private static dynamic GetValue()
{
    return "dynamics are useful!";
}

Dynamisches Objekt mit Eigenschaften erstellen

using System;
using System.Dynamic;

dynamic info = new ExpandoObject();
info.Id = 123;
info.Another = 456;

Console.WriteLine(info.Another);
// 456

Console.WriteLine(info.DoesntExist);
// Throws RuntimeBinderException

Umgang mit bestimmten Typen, die zur Kompilierzeit unbekannt sind

Die folgenden Ergebnisse liefern gleichwertige Ergebnisse:

class IfElseExample
{
    public string DebugToString(object a)
    {
        if (a is StringBuilder)
        {
            return DebugToStringInternal(a as StringBuilder);
        }
        else if (a is List<string>)
        {
            return DebugToStringInternal(a as List<string>);
        }
        else
        {
            return a.ToString();
        }
    }

    private string DebugToStringInternal(object a)
    {
        // Fall Back
        return a.ToString();
    }

    private string DebugToStringInternal(StringBuilder sb)
    {
        return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}";
    }

    private string DebugToStringInternal(List<string> list)
    {
        return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t" + string.Join(Environment.NewLine + "\t", list.ToArray())}";
    }
}

class DynamicExample
{
    public string DebugToString(object a)
    {
        return DebugToStringInternal((dynamic)a);
    }

    private string DebugToStringInternal(object a)
    {
        // Fall Back
        return a.ToString();
    }

    private string DebugToStringInternal(StringBuilder sb)
    {
        return $"StringBuilder - Capacity: {sb.Capacity}, MaxCapacity: {sb.MaxCapacity}, Value: {sb.ToString()}";
    }

    private string DebugToStringInternal(List<string> list)
    {
        return $"List<string> - Count: {list.Count}, Value: {Environment.NewLine + "\t" + string.Join(Environment.NewLine + "\t", list.ToArray())}";
    }
}

Der Vorteil der Dynamik besteht darin, einen neuen Typ zum Behandeln hinzuzufügen, wobei nur eine Überladung von DebugToStringInternal des neuen Typs erforderlich ist. Es entfällt auch die Notwendigkeit, den Typ manuell zu erstellen.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow