Question Quels sont les vrais avantages d'ExpandoObject?


le ExpandoObject La classe ajoutée à .NET 4 vous permet de définir arbitrairement des propriétés sur un objet lors de l'exécution.

Y a-t-il des avantages à cela sur l'utilisation d'un Dictionary<string,object>, ou vraiment même un Hashtable? Pour autant que je sache, ce n'est rien d'autre qu'une table de hachage à laquelle vous pouvez accéder avec une syntaxe un peu plus succincte.

Par exemple, pourquoi est-ce:

dynamic obj = new ExpandoObject();
obj.MyInt = 3;
obj.MyString = "Foo";
Console.WriteLine(obj.MyString);

Vraiment mieux ou sensiblement différent de:

var obj = new Dictionary<string, object>();
obj["MyInt"] = 3;
obj["MyString"] = "Foo";

Console.WriteLine(obj["MyString"]);

Quelle réal On obtient des avantages en utilisant ExpandoObject au lieu de simplement utiliser un type de dictionnaire arbitraire, sauf qu'il n'est pas évident que vous utilisez un type qui va être déterminé au moment de l'exécution.


506
2017-10-31 01:09


origine


Réponses:


Depuis que j'ai écrit l'article MSDN dont vous parlez, je suppose que je dois répondre à celui-ci.

Premièrement, j'ai anticipé cette question et c'est pourquoi j'ai écrit un article de blog qui montre un cas d'utilisation plus ou moins réel pour ExpandoObject: Dynamique en C # 4.0: Présentation de ExpandoObject.

En bref, ExpandoObject peut vous aider à créer des objets hiérarchiques complexes. Par exemple, imaginez que vous avez un dictionnaire dans un dictionnaire:

Dictionary<String, object> dict = new Dictionary<string, object>();
Dictionary<String, object> address = new Dictionary<string,object>();
dict["Address"] = address;
address["State"] = "WA";
Console.WriteLine(((Dictionary<string,object>)dict["Address"])["State"]);

Plus la hiérarchie est profonde, plus le code est mauvais. Avec ExpandoObject, il reste élégant et lisible.

dynamic expando = new ExpandoObject();
expando.Address = new ExpandoObject();
expando.Address.State = "WA";
Console.WriteLine(expando.Address.State);

Deuxièmement, comme cela a déjà été souligné, ExpandoObject implémente l'interface INotifyPropertyChanged qui vous donne plus de contrôle sur les propriétés qu'un dictionnaire.

Enfin, vous pouvez ajouter des événements à ExpandoObject comme ici:

class Program
{

   static void Main(string[] args)
   {
       dynamic d = new ExpandoObject();

       // Initialize the event to null (meaning no handlers)
       d.MyEvent = null;

       // Add some handlers
       d.MyEvent += new EventHandler(OnMyEvent);
       d.MyEvent += new EventHandler(OnMyEvent2);

       // Fire the event
       EventHandler e = d.MyEvent;

       if (e != null)
       {
           e(d, new EventArgs());
       }

       // We could also fire it with...
       //      d.MyEvent(d, new EventArgs());

       // ...if we knew for sure that the event is non-null.
   }

   static void OnMyEvent(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent fired by: {0}", sender);
   }

   static void OnMyEvent2(object sender, EventArgs e)
   {
       Console.WriteLine("OnMyEvent2 fired by: {0}", sender);
   }
}

609
2017-11-02 19:06



Un avantage est pour les scénarios de liaison. Les grilles de données et les grilles de propriétés récupèrent les propriétés dynamiques via le système TypeDescriptor. En outre, la liaison de données WPF comprend les propriétés dynamiques, de sorte que les contrôles WPF peuvent se lier à un ExpandoObject plus facilement qu'un dictionnaire.

L'interopérabilité avec les langages dynamiques, qui attendront des propriétés DLR plutôt que des entrées de dictionnaire, peut également être prise en compte dans certains scénarios.


69
2017-10-31 01:17



Le véritable avantage pour moi est la liaison de données sans effort de XAML:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

 <TextBlock Text="{Binding SomeData.WhatEver}" />

35
2017-07-01 11:51



Interop avec d'autres langues fondées sur le DLR est la raison # 1 que je peux penser. Vous ne pouvez pas leur passer un Dictionary<string, object> comme ce n'est pas un IDynamicMetaObjectProvider. Un autre avantage supplémentaire est qu'il met en œuvre INotifyPropertyChanged ce qui signifie dans le monde de la liaison de données de WPF, il a également ajouté des avantages au-delà de ce que Dictionary<K,V> peut vous fournir.


24
2017-10-31 01:19



Tout est une question de commodité pour les programmeurs. Je peux imaginer écrire des programmes rapides et sales avec cet objet.


18
2017-10-31 01:15



Je pense que cela aura un avantage syntaxique puisque vous ne ferez plus de "fausses" propriétés ajoutées dynamiquement en utilisant un dictionnaire.

Cela, et interagir avec des langues dynamiques, je pense.


13
2017-10-31 01:19



C'est un exemple de bon Article MSDN sur l'utilisation ExpandoObject pour créer des types ad-hoc dynamiques pour les données structurées entrantes (par exemple XML, Json).

Nous pouvons également affecter un délégué à ExpandoObjectPropriété dynamique:

dynamic person = new ExpandoObject();
person.FirstName = "Dino";
person.LastName = "Esposito";

person.GetFullName = (Func<String>)(() => { 
  return String.Format("{0}, {1}", 
    person.LastName, person.FirstName); 
});

var name = person.GetFullName();
Console.WriteLine(name);

Cela nous permet donc d'injecter de la logique dans un objet dynamique lors de l'exécution. Par conséquent, avec les expressions lambda, les fermetures, les mots clés dynamiques et Classe DynamicObject, nous pouvons introduire quelques éléments de programmation fonctionnelle dans notre code C #, que nous connaissons à partir de langages dynamiques comme le JavaScript ou le PHP.


9
2017-11-26 16:10