Recherche…


Remarques

Le mot clé dynamic déclare une variable dont le type n'est pas connu à la compilation. Une variable dynamic peut contenir n'importe quelle valeur et le type de la valeur peut changer au cours de l'exécution.

Comme indiqué dans le livre "Métaprogrammation en .NET", C # n’a pas de type de support pour le mot clé dynamic :

La fonctionnalité activée par le mot clé dynamic est un ensemble intelligent d'actions de compilation qui émettent et utilisent des objets CallSite dans le conteneur de site de la portée d'exécution locale. Le compilateur gère ce que les programmeurs perçoivent comme des références d'objets dynamiques via ces instances CallSite . Les paramètres, les types de retour, les champs et les propriétés qui reçoivent un traitement dynamique au moment de la compilation peuvent être marqués de certaines métadonnées pour indiquer qu'ils ont été générés pour une utilisation dynamique, mais le type de données sous-jacent sera toujours System.Object .

Créer une variable dynamique

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

Retour dynamique

using System;

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

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

Créer un objet dynamique avec des propriétés

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

Gestion de types spécifiques inconnus à la compilation

Les résultats équivalents suivants en sortie:

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())}";
    }
}

L'avantage de la dynamique, l'ajout d'un nouveau type à gérer nécessite simplement l'ajout d'une surcharge de DebugToStringInternal du nouveau type. Élimine également le besoin de le lancer manuellement au type.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow