Utilisation de type dynamique

Le type dynamic est un type statique ; toutefois, un objet de type dynamic ignore la vérification des types statiques. Dans la plupart des cas, il fonctionne comme s’il était de type object. Le compilateur suppose qu’un élément dynamic prend en charge n’importe quelle opération. Par conséquent, vous n’avez pas besoin de déterminer si l’objet obtient sa valeur à partir d’une COM API, à partir d’un langage dynamique tel que IronPython, du modèle DOM (Document Object Model) HTML, de la réflexion ou d’un autre endroit dans le programme. Toutefois, si le code n’est pas valide, les erreurs s’affichent au moment de l’exécution.

Par exemple, si la méthode d’instance exampleMethod1 dans le code suivant n’a qu’un seul paramètre, le compilateur reconnaît que le premier appel à la méthode, ec.exampleMethod1(10, 4), n’est pas valide, car il contient deux arguments. Cet appel entraîne une erreur du compilateur. Le compilateur ne vérifie pas le deuxième appel à la méthode, dynamic_ec.exampleMethod1(10, 4), car le type de dynamic_ec est dynamic. Par conséquent, aucune erreur de compilateur n’est signalée. Toutefois, l’erreur ne s’échappe pas indéfiniment. Elle apparaît au moment de l’exécution et provoque une exception d’exécution.

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) { }
}

Le rôle du compilateur dans ces exemples consiste à empaqueter des informations sur ce que chaque instruction propose de faire à l’objet ou à l’expression dynamic. Le runtime examine les informations stockées et toute instruction qui n’est pas valide provoque une exception d’exécution.

Le résultat de la plupart des opérations dynamiques est lui-même de type dynamic. Par exemple, si vous placez le pointeur de la souris sur testSum dans l’exemple suivant, IntelliSense affiche le type (variable locale) dynamic testSum.

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

Les opérations dans lesquelles le résultat n’est pas dynamic sont les suivantes :

  • Les conversions de dynamic vers un autre type.
  • Les appels de constructeur qui incluent des arguments de type dynamic.

Par exemple, le type de testInstance dans la déclaration suivante est ExampleClass, et non pas dynamic :

var testInstance = new ExampleClass(d);

Conversions

Les conversions entre des objets dynamiques et d’autres types sont faciles à exécuter. Les conversions permettent au développeur de basculer entre le comportement dynamique et non dynamique.

Vous pouvez convertir tout en dynamic implicitement, comme illustré dans les exemples suivants.

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

À l’inverse, vous pouvez appliquer dynamiquement n’importe quelle conversion implicite à n’importe quelle expression de type dynamic.

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

Résolution de surcharge avec des arguments de type dynamic

La résolution de surcharge a lieu au moment de l’exécution, et non pas au moment de la compilation, si un ou plusieurs arguments d’un appel de méthode sont de type dynamic, ou si le récepteur de l’appel de méthode est de type dynamic. Dans l’exemple suivant, si la seule méthode exampleMethod2 accessible prend un argument de chaîne, l’envoi de d1 en tant qu’argument n’entraîne pas d’erreur du compilateur, mais provoque une exception d’exécution. La résolution de surcharge échoue au moment de l’exécution car le type de d1 est int, et exampleMethod2 exige une chaîne.

// 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

Le runtime de langage dynamique (DLR) fournit l’infrastructure qui prend en charge le type dynamic en C#, ainsi que l’implémentation de langages de programmation dynamiques tels que IronPython et IronRuby. Pour plus d’informations sur le DLR, consultez Vue d’ensemble du Dynamic Language Runtime.

COM interop

De nombreuses méthodes COM autorisent une variation des types d’arguments et du type de retour en désignant les types comme object. L’interopérabilité COM nécessite un cast explicite des valeurs à coordonner avec des variables fortement typées en C#. Si vous effectuez la compilation à l’aide de l’option EmbedInteropTypes (Options de compilateur C# ), l’introduction du type dynamic vous permet de traiter les occurrences d’object dans les signatures COM comme si elles étaient de type dynamic, vous évitant ainsi une grande partie des opérations de cast. Pour plus d’informations sur l’utilisation du type dynamic avec des objets COM, consultez l’article sur Comment accéder aux objets Office Interop à l’aide des fonctionnalités C#.

Intitulé Description
dynamic Décrit l’utilisation du mot clé dynamic.
Vue d’ensemble du Dynamic Language Runtime Fournit une vue d’ensemble du DLR, qui est un environnement d’exécution ajoutant au Common Language Runtime (CLR) un ensemble de services pour les langages dynamiques.
Procédure pas à pas : création et utilisation d’objets dynamiques Fournit des instructions pas à pas pour la création d’un objet dynamique personnalisé et pour la création d’un projet qui accède à une bibliothèque IronPython.