Dalam javascript Anda dapat mendeteksi apakah suatu properti didefinisikan dengan menggunakan kata kunci yang tidak ditentukan:
if( typeof data.myProperty == "undefined" ) ...
Bagaimana Anda melakukan ini dalam C # menggunakan kata kunci dinamis dengan ExpandoObject
dan tanpa membuang pengecualian?
c#
dynamic
expandoobject
Softlion
sumber
sumber
data.myProperty
; memeriksa apa yangtypeof data.myProperty
kembali. Benar bahwadata.myProperty
mungkin ada dan diaturundefined
, tetapi dalam kasus itu,typeof
akan mengembalikan sesuatu selain"undefined"
. Jadi kode ini berfungsi.Jawaban:
Menurut MSDN deklarasi menunjukkan sedang mengimplementasikan IDictionary:
Anda dapat menggunakan ini untuk melihat apakah seorang anggota didefinisikan:
sumber
Perbedaan penting perlu dibuat di sini.
Sebagian besar jawaban di sini khusus untuk ExpandoObject yang disebutkan dalam pertanyaan. Tetapi penggunaan umum (dan alasan untuk mendarat pada pertanyaan ini saat mencari) adalah ketika menggunakan ASP.Net MVC ViewBag. Itu adalah implementasi kustom / subkelas DynamicObject, yang tidak akan membuang Pengecualian ketika Anda memeriksa sembarang nama properti arbitrer untuk null. Misalkan Anda dapat mendeklarasikan properti seperti:
Lalu anggaplah Anda ingin memeriksa nilainya, dan apakah itu disetel - apakah ada. Berikut ini adalah valid, akan dikompilasi, tidak akan memberikan pengecualian, dan memberi Anda jawaban yang benar:
Sekarang singkirkan deklarasi EnableThinger. Kode yang sama mengkompilasi dan berjalan dengan benar. Tidak perlu refleksi.
Tidak seperti ViewBag, ExpandoObject akan melempar jika Anda memeriksa nol pada properti yang tidak ada. Untuk mendapatkan fungsionalitas MVC ViewBag yang lebih lembut dari
dynamic
objek Anda, Anda harus menggunakan implementasi dinamis yang tidak melempar.Anda bisa menggunakan implementasi yang tepat di MVC ViewBag:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DynamicViewDataDictionary.cs
Anda dapat melihatnya diikat ke Tampilan MVC di sini, di MVC ViewPage:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
Kunci perilaku anggun DynamicViewDatationary adalah implementasi Kamus di ViewDataDictionary, di sini:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
Dengan kata lain, itu selalu mengembalikan nilai untuk semua kunci, terlepas dari apa yang ada di dalamnya - itu hanya mengembalikan nol ketika tidak ada di sana. Tapi, ViewDataDictionary memiliki beban terikat dengan Model MVC, jadi lebih baik untuk menghapus hanya bagian kamus yang anggun untuk digunakan di luar Tampilan MVC.
Terlalu lama untuk benar-benar memposting semua nyali di sini - sebagian besar hanya menerapkan IDictionary - tapi di sini ada objek dinamis (kelas
DDict
) yang tidak membuang pemeriksaan nol pada properti yang belum dideklarasikan, di Github:https://github.com/b9chris/GracefulDynamicDictionary
Jika Anda hanya ingin menambahkannya ke proyek Anda melalui NuGet, namanya GracefulDynamicDictionary .
sumber
Saya menjawab pertanyaan yang sangat mirip baru-baru ini: Bagaimana cara saya merefleksikan anggota objek dinamis?
Singkatnya, ExpandoObject bukan satu-satunya objek dinamis yang mungkin Anda dapatkan. Refleksi akan berfungsi untuk tipe statis (tipe yang tidak mengimplementasikan IDynamicMetaObjectProvider). Untuk tipe yang mengimplementasikan antarmuka ini, refleksi pada dasarnya tidak berguna. Untuk ExpandoObject, Anda cukup memeriksa apakah properti didefinisikan sebagai kunci dalam kamus yang mendasarinya. Untuk implementasi lain, ini mungkin menantang dan terkadang satu-satunya cara adalah bekerja dengan pengecualian. Untuk detailnya, ikuti tautan di atas.
sumber
DIPERBARUI: Anda dapat menggunakan delegasi dan mencoba untuk mendapatkan nilai dari properti objek dinamis jika ada. Jika tidak ada properti, cukup tangkap pengecualian dan kembalikan false.
Coba lihat, ini berfungsi dengan baik untuk saya:
Output dari kode adalah sebagai berikut:
sumber
IsPropertyExist
. Dalam contoh ini, Anda tahu seseorang dapat melemparInvalidOperationException
. Dalam praktiknya, Anda tidak tahu pengecualian apa yang dapat diberikan. +1 untuk menangkal kultus kargo.Saya ingin membuat metode ekstensi sehingga saya bisa melakukan sesuatu seperti:
... tetapi Anda tidak dapat membuat ekstensi
ExpandoObject
sesuai dengan dokumentasi C # 5 (info lebih lanjut di sini ).Jadi saya akhirnya membuat pembantu kelas:
Untuk menggunakannya:
sumber
Mengapa Anda tidak ingin menggunakan Reflection untuk mendapatkan set jenis properyes? Seperti ini
sumber
Metode ekstensi ini memeriksa keberadaan properti dan kemudian mengembalikan nilai atau nol. Ini berguna jika Anda tidak ingin aplikasi Anda melemparkan pengecualian yang tidak perlu, setidaknya yang dapat Anda bantu.
Jika bisa digunakan seperti itu:
atau jika variabel lokal Anda 'dinamis', Anda harus melemparkannya ke ExpandoObject terlebih dahulu.
sumber
Bergantung pada use case Anda, jika null dapat dianggap sama dengan undefined, Anda dapat mengubah ExpandoObject Anda menjadi DynamicJsonObject.
Keluaran:
sumber
sumber
Hai teman-teman berhenti menggunakan Refleksi untuk semua hal yang menghabiskan banyak siklus CPU.
Ini solusinya:
sumber
Coba yang ini
sumber
dynamic
objek (selalu kembalinull
).