it-swarm.asia

ما هي الفوائد الحقيقية لـ ExpandoObject؟

ExpandoObject class التي تتم إضافتها إلى .NET 4 تسمح لك بتعيين الخصائص بشكل تعسفي إلى كائن في وقت التشغيل.

هل هناك أي مزايا لهذا عبر استخدام Dictionary<string, object> ، أو حتى Hashtable ؟ بقدر ما أستطيع أن أقول ، هذا ليس سوى جدول تجزئة يمكنك الوصول إليه باستخدام بناء جملة مختصرة قليلاً.

على سبيل المثال ، لماذا هذا:

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

حقا أفضل ، أو مختلفة إلى حد كبير ، من:

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

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

ما حقيقي المزايا يتم اكتسابها باستخدام ExpandoObject بدلاً من مجرد استخدام نوع القاموس التعسفي ، بخلاف عدم التوضيح أنك تستخدم نوعًا سيتم تحديده في وقت التشغيل.

553
Reed Copsey

منذ أن كتبت مقالة MSDN التي تشير إليها ، أعتقد أنه يجب علي الإجابة على هذا المقال.

أولاً ، لقد توقعت هذا السؤال وهذا هو السبب في أنني كتبت منشورًا على مدونة يعرض حالة استخدام حقيقية إلى حد ما لـ ExpandoObject: Dynamic in C # 4.0: Introducing ExpandoObject .

بعد قليل ، يمكن لـ ExpandoObject مساعدتك في إنشاء كائنات هرمية معقدة. على سبيل المثال ، تخيل أن لديك قاموسًا داخل القاموس:

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"]);

الأعمق هو التسلسل الهرمي ، وأقبح هو رمز. مع ExpandoObject يبقى أنيقة وقابلة للقراءة.

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

ثانياً ، كما تمت الإشارة بالفعل ، تطبق ExpandoObject واجهة INotifyPropertyChanged والتي تمنحك تحكمًا أكبر في الخصائص أكثر من القاموس.

أخيرًا ، يمكنك إضافة أحداث إلى ExpandoObject مثل هنا:

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);
   }
}
655
Alexandra Rusina

ميزة واحدة هي لسيناريوهات الربط. سوف تلتقط شبكات البيانات وشبكات الممتلكات الخصائص الديناميكية عبر نظام TypeDescriptor. بالإضافة إلى ذلك ، ستفهم عملية ربط بيانات WPF الخصائص الديناميكية ، لذلك يمكن لعناصر تحكم WPF ربط ExpandoObject بسهولة أكبر من القاموس.

قد تكون إمكانية التشغيل المتداخل مع اللغات الديناميكية ، والتي ستتوقع خصائص DLR بدلاً من إدخالات القاموس ، أحد الاعتبارات في بعض السيناريوهات.

74
itowlson

الفائدة الحقيقية بالنسبة لي هي الربط التام للبيانات من XAML:

public dynamic SomeData { get; set; }

...

SomeData.WhatEver = "Yo Man!";

...

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

التفاعل مع اللغات الأخرى التي تأسست على DLR هو السبب الأول الذي يمكنني التفكير فيه. لا يمكنك تمريرها Dictionary<string, object> لأنها ليست IDynamicMetaObjectProvider. فائدة إضافية أخرى هي أنها تطبق INotifyPropertyChanged مما يعني في عالم ربط البيانات الخاص بـ WPF أنه أضاف أيضًا فوائد تتجاوز ما يمكن أن يوفره Dictionary<K,V> لك.

27
Drew Marsh

كل شيء عن راحة المبرمج. أستطيع أن أتخيل كتابة برامج سريعة وقذرة مع هذا الكائن.

19
ChaosPandion

أعتقد أنه سيكون له فائدة في بناء الجملة ، حيث أنك لن تعد "تزييف" خصائص تمت إضافتها ديناميكيًا باستخدام قاموس.

ذلك ، والتفاعل مع لغات ديناميكية أعتقد.

14
gn22

إنه مثال من مقالة رائعة MSDN حول استخدام ExpandoObject لإنشاء أنواع مخصصة ديناميكية للبيانات المهيكلة الواردة (مثل XML و Json).

يمكننا أيضًا تعيين مفوض إلى خاصية ديناميكية ExpandoObject :

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);

وبالتالي فإنه يسمح لنا بحقن بعض المنطق في كائن ديناميكي في وقت التشغيل. لذلك ، إلى جانب تعبيرات lambda والإغلاقات والكلمات الرئيسية الديناميكية و فئة DynamicObject ، يمكننا تقديم بعض عناصر البرمجة الوظيفية في رمز C # الخاص بنا ، والذي نعرفه من اللغات الديناميكية مثل JavaScript أو PHP.

11
sgnsajgon

هناك بعض الحالات التي يكون فيها هذا مفيدًا. سوف أستخدمه في شل المعياري على سبيل المثال. تحدد كل وحدة نمط حوار التكوين الخاص بها مرتبطًا بإعداداته. أقدم لها ExpandoObject لأنه Datacontext واحفظ القيم في التخزين التكوين الخاص بي. بهذه الطريقة ، يجب على كاتب حوار التكوين فقط الربط بقيمة ويتم إنشاؤه وحفظه تلقائيًا. (والمقدمة إلى وحدة لاستخدام هذه الإعدادات بالطبع)

إنه ببساطة أسهل في الاستخدام من القاموس. لكن الجميع يجب أن يدركوا أنه داخليًا مجرد قاموس.

انها مثل LINQ فقط السكر النحوي ، لكنه يجعل الأمور أسهل في بعض الأحيان.

للإجابة على سؤالك مباشرة: من الأسهل الكتابة وأسهل في القراءة. ولكن من الناحية الفنية ، فهي في الأساس Dictionary<string,object> (يمكنك حتى وضعها في قائمة واحدة لإدراج القيم).

4
n1LWeb