Karena saya menulis artikel MSDN yang Anda maksud, saya kira saya harus menjawab yang ini.
Pertama, saya mengantisipasi pertanyaan ini dan itulah sebabnya saya menulis posting blog yang menunjukkan kasus penggunaan yang kurang lebih nyata untuk ExpandoObject: Dynamic di C # 4.0: Memperkenalkan ExpandoObject .
Singkatnya, ExpandoObject dapat membantu Anda membuat objek hierarkis yang kompleks. Misalnya, bayangkan Anda memiliki kamus di dalam kamus:
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"]);
Semakin dalam adalah hierarki, yang lebih buruk adalah kode. Dengan ExpandoObject tetap elegan dan mudah dibaca.
dynamic expando = new ExpandoObject();
expando.Address = new ExpandoObject();
expando.Address.State = "WA";
Console.WriteLine(expando.Address.State);
Kedua, seperti yang sudah ditunjukkan, ExpandoObject mengimplementasikan antarmuka INotifyPropertyChanged yang memberi Anda lebih banyak kontrol atas properti daripada kamus.
Akhirnya, Anda dapat menambahkan acara ke ExpandoObject seperti di sini:
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;
e?.Invoke(d, new EventArgs());
}
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);
}
}
Juga, ingatlah bahwa tidak ada yang menghalangi Anda untuk menerima argumen peristiwa secara dinamis. Dengan kata lain, alih-alih menggunakan EventHandler
, Anda dapat menggunakan EventHandler<dynamic>
yang akan menyebabkan argumen kedua dari pawang menjadi dynamic
.
d.MyEvent = null;
, Atau tidak?var expando = new { Address = new { State = "WA" } }; Console.WriteLine(expando.Address.State);
Saya menemukan ini lebih mudah dibaca tetapi ymmv. Dan mengingat itu diketik secara statis, itu lebih berguna dalam konteks ini.Satu keuntungan adalah untuk skenario yang mengikat. Kisi data dan kisi properti akan mengambil properti dinamis melalui sistem TypeDescriptor. Selain itu, pengikatan data WPF akan memahami properti dinamis, sehingga kontrol WPF dapat berikatan dengan ExpandoObject lebih mudah daripada kamus.
Interoperabilitas dengan bahasa dinamis, yang akan mengharapkan properti DLR daripada entri kamus, juga dapat menjadi pertimbangan dalam beberapa skenario.
sumber
List<dynamic>
danIEnumerable<dynamic>
menggunakan WPF4Manfaat nyata bagi saya adalah pengikatan data yang benar-benar mudah dari XAML:
...
...
sumber
Interop dengan bahasa lain yang ditemukan pada
DLR
alasan # 1 itu bisa saya pikirkan. Anda tidak dapat melewati merekaDictionary<string, object>
karena ini bukanIDynamicMetaObjectProvider
. Manfaat tambahan lainnya adalah mengimplementasikannyaINotifyPropertyChanged
yang berarti dalam dunia penyatuan data WPF, ia juga memiliki manfaat tambahan di luar apa yangDictionary<K,V>
dapat Anda berikan.sumber
Ini semua tentang kenyamanan programmer. Saya bisa membayangkan menulis program cepat dan kotor dengan objek ini.
sumber
Saya pikir ini akan memiliki manfaat sintaksis, karena Anda tidak akan lagi "memalsukan" properti yang ditambahkan secara dinamis dengan menggunakan kamus.
Itu, dan interop dengan bahasa dinamis saya akan berpikir.
sumber
Ini adalah contoh dari artikel MSDN yang hebat tentang penggunaan ExpandoObject untuk membuat tipe ad-hoc dinamis untuk data terstruktur yang masuk (yaitu XML, Json).
Kami juga dapat menetapkan delegasi ke properti dinamis ExpandoObject :
Dengan demikian memungkinkan kita untuk menyuntikkan beberapa logika ke objek dinamis saat runtime. Oleh karena itu, bersama dengan ekspresi lambda, penutupan, kata kunci dinamis, dan kelas DynamicObject , kami dapat memperkenalkan beberapa elemen pemrograman fungsional ke dalam kode C # kami, yang kami tahu dari bahasa dinamis seperti JavaScript atau PHP.
sumber
Ada beberapa kasus di mana ini berguna. Saya akan menggunakannya untuk shell Modularized misalnya. Setiap modul mendefinisikan Dialog Konfigurasi itu sendiri yang didasari oleh pengaturannya. Saya memberinya ExpandoObject karena Datacontext dan menyimpan nilai-nilai dalam Storage konfigurasi saya. Dengan cara ini penulis Dialog Konfigurasi hanya harus Mengikat ke Nilai dan secara otomatis dibuat dan disimpan. (Dan disediakan untuk modul untuk menggunakan pengaturan ini tentu saja)
Ini lebih mudah digunakan daripada Kamus. Tetapi semua orang harus sadar bahwa secara internal itu hanya sebuah Kamus.
Ini seperti LINQ hanya gula sintaksis, tetapi kadang-kadang membuatnya lebih mudah.
Jadi untuk menjawab pertanyaan Anda secara langsung: Lebih mudah untuk menulis dan lebih mudah dibaca. Tetapi secara teknis itu pada dasarnya adalah
Dictionary<string,object>
(Anda bahkan dapat memasukkannya ke dalam daftar nilai).sumber
Saya pikir itu hanya berfungsi karena semuanya memiliki ToString (), jika tidak, Anda harus tahu tipe itu dan melemparkan 'objek' ke tipe itu.
Beberapa di antaranya bermanfaat lebih sering daripada yang lain, saya mencoba untuk teliti.
Mungkin jauh lebih alami untuk mengakses koleksi, dalam hal ini apa yang secara efektif "kamus", menggunakan notasi titik lebih langsung.
Sepertinya ini bisa digunakan sebagai Tuple yang sangat bagus. Anda masih dapat memanggil anggota Anda "Item1", "Item2" dll ... tetapi sekarang Anda tidak harus, itu juga bisa berubah, tidak seperti Tuple. Ini memang memiliki kelemahan besar dari kurangnya dukungan intellisense.
Anda mungkin merasa tidak nyaman dengan "nama anggota sebagai string", seperti halnya merasakan dengan kamus, Anda mungkin merasa itu terlalu seperti "mengeksekusi string", dan itu dapat menyebabkan konvensi penamaan dikodekan, dan berurusan dengan bekerja dengan morfem dan suku kata ketika kode mencoba memahami cara menggunakan anggota :-P
Bisakah Anda memberikan nilai pada ExpandoObject itu sendiri atau hanya anggotanya? Bandingkan dan kontras dengan dinamis / dinamis [], gunakan mana yang paling sesuai dengan kebutuhan Anda.
Saya tidak berpikir dynamic / dynamic [] bekerja dalam loop foreach, Anda harus menggunakan var, tetapi mungkin Anda dapat menggunakan ExpandoObject.
Anda tidak dapat menggunakan dinamis sebagai anggota data di kelas, mungkin karena itu setidaknya semacam kata kunci, semoga Anda bisa dengan ExpandoObject.
Saya berharap itu "adalah" sebuah ExpandoObject, mungkin berguna untuk melabeli hal-hal yang sangat umum, dengan kode yang membedakan berdasarkan jenis di mana ada banyak hal dinamis yang digunakan.
Bersikap baik jika Anda bisa menelusuri beberapa level sekaligus.
Itu bukan contoh terbaik, bayangkan penggunaan elegan yang sesuai dalam proyek Anda sendiri.
Sayang sekali Anda tidak dapat membuat kode ini dan mendorong hasilnya ke intellisense. Saya tidak yakin bagaimana ini akan bekerja.
Bersikap baik jika mereka dapat memiliki nilai serta anggota.
sumber
Setelah valueTuples, apa gunanya kelas ExpandoObject? kode 6 baris ini dengan ExpandoObject:
dapat ditulis dalam satu baris dengan tuple:
selain itu dengan sintaks tuple Anda memiliki inferensi tipe yang kuat dan dukungan intlisense
sumber