Pour bien comprendre en détail le fonctionnement de dynamic en C#4, tu
peux
lire 'C# in Depth 2' de John Skeet (editions Mannings)
http://www.manning.com/skeet2/
Quand tu déclare une variable dynamic, le compilateur va utiliser
une variable de type object, eventuellement marquée avec un attribut
(pour les fields, les arguments de méthode, les valeurs de retour
etc).
Pour toute oppération éffectuée sur cette variable, le compilateur
crée
un 'call site', un concept du DLR qui va se charger d'executer
l'opération
en question.
Quand C# crée un call site, il passe un binder C# (contenue dans
l'assembly
Microsoft.CSharp.dll) qui sera utilisé par le DLR pour éffectuer les
opérations
dynamic conformement au comportement classique de C# une fois les
types
résolus dynamiquement.
Si l'objet passé implemente IDynamicMetaObject, cet objet peut alors
interpreter
lui même l'appel dynamique effectué. L'implementation par defaut de
cette interface
(DynamicObject) laisse implmenenter des methodes telles que TryInvoke
(pour
les invocations de méthodes), TryGetMember pour les get sur les
propriétés etc.
Si l'objet est un objet .net qui n'implemente pas l'interface, le
binder tente simplement
de trouver une méthode qui correspond à l'appel demandé selon les
regles classiques
de résolution de surcharge de C#.
Sans forcement implementer IDynamicMetaObject, dynamic peut être très
utile
pour éviter tout un tas de relection lors des switchs sur les types
d'arguments.
Au lieu de :
void ConsumeMessage(Message message)
{
if (message is SomeMessage)
ConsumeMessage((SomeMessage)message);
else if (message is SomeOtherMessage)
ConsumeMessage((SomeOtherMessage)message);
else if (message is AnotherMessage)
ConsumeMessage((AnotherMessage)message);
}
ou des version avec beaucoup de Reflection pour créer un dictionnaire
de dispatch en fonction du type :
void ConsumeMessage(Message message)
{
IConsumer consumer;
if (!consumers.TryGetValue(message.GetType(), out conumer)
{
// crée un consumer par réflection à partir du type de message
pour appeler la bonne methode..
}
consumer.Consume(message);
}
on peut tout simplement faire :
void ConsumeMessage(Message message)
{
Consume((dynamic)message);
}
void Consume(SomeMessage m)
{
}
void Consume(SomeOtherMessage m)
{
}
void Consume(AnotherMessage m)
{
}
La ligne Consume((dynamic)message) va créer un call site de le but
sera d'appeler une methode nommée Consume prennant l'objet message
indiqué, ayant 3 overloads, le binder va déterminer celui qui convient
en fonction du type runtime du message.
Le compilateur est malin, si vous faite un appel qui quelque soient
les parametre ne pourra pas aboutir, il vous l'indiquera !
Je suis sur qu'on va vite trouver d'autres avantages à dynamic meme
sans pour autant faire de l'active record...
On 7 août, 16:28, DUVAL Olivier <
zork...@gmail.com> wrote:
> Merci Jb pour cette explication simple et claire - vivement 2010 ;)
> 2009/8/7 Jb Evain <
j...@nurv.fr>
>
>
>
>
>
>
>
> > Yo,
>
> > On 8/7/09, DUVAL Olivier <
zork...@gmail.com> wrote:
> > > A la machine à café je me posais la question suivante : pour la future
> > > version de .NET (v4), notamment C# 4 et l'arrivée du dynamic, comment
> > > sont-ils arrivés à faire ça ?
>
> > > la CLR est-elle remplacée totalement par la DLR ? mix des 2 ? DLR
> > inclut
> > > dans la CLR ? autre ?
>
> > La DLR est juste un ensemble de classes managées sur lesquelles se
> > reposent les implémentations des langages dynamiques sur .net.
>
> > La DLR ne nécessite pas de changement de la CLR, elle fonctionne aussi
> > sur bien sur une CLR 2.0 qu'une CLR 4.0.
>
> > Quand on utilise le mot clef dynamic en C#4, le compilateur va ajouter
> > des appels à la librairie Microsoft.CSharp.dll, qui est une librairie
> > qui utilise la DLR pour faire communiquer le monde statique de C# avec
> > celui, et bien, dynamique, d'ailleurs.
>
> > Rien de bien compliqué, au final ;)
>
> > --
> > Jb Evain <
j...@nurv.fr>
>
> --
> Olivier DUVALhttp://olivier-duval.info- Masquer le texte des messages précédents -
>
> - Afficher le texte des messages précédents -