Saya memiliki blok kode yang membuat serial suatu jenis menjadi tag Html.
Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T
tagBuilder.Attributes.Add("class", t.Name);
foreach (PropertyInfo prop in t.GetProperties())
{
object propValue = prop.GetValue(myObj, null);
string stringValue = propValue != null ? propValue.ToString() : String.Empty;
tagBuilder.Attributes.Add(prop.Name, stringValue);
}
Ini karya besar, kecuali saya ingin hanya melakukan ini untuk tipe primitif, seperti int
, double
, bool
dll, dan jenis lainnya yang tidak primitif tapi dapat serial dengan mudah seperti string
. Saya ingin mengabaikan hal lain seperti Daftar & jenis kustom lainnya.
Adakah yang bisa menyarankan bagaimana saya melakukan ini? Atau apakah saya perlu menentukan tipe yang ingin saya izinkan di suatu tempat dan mengaktifkan tipe properti untuk melihat apakah itu diperbolehkan? Itu agak berantakan, jadi alangkah baiknya jika saya ada cara yang lebih rapi.
c#
reflection
primitive-types
DaveDev
sumber
sumber
System.String
bukan tipe primitif.Jawaban:
Anda dapat menggunakan properti
Type.IsPrimitive
, tetapi berhati-hatilah karena ada beberapa tipe yang dapat kita anggap primitif, tetapi mereka tidak, misalnyaDecimal
danString
.Sunting 1: Menambahkan kode sampel
Berikut ini contoh kode:
Sunting 2: Seperti komentar @SLaks , ada jenis lain yang mungkin ingin Anda perlakukan sebagai primitif. Saya pikir Anda harus menambahkan variasi ini satu per satu .
Sunting 3: IsPrimitive = (Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, dan Single), jenis Anther Primitive-like untuk memeriksa (t == typeof (DateTime) ))
sumber
DateTime
,TimeSpan
danDateTimeOffset
.||
), bukan bitwise atau (|
).Saya baru saja menemukan pertanyaan ini sambil mencari solusi yang serupa, dan berpikir Anda mungkin tertarik pada pendekatan berikut menggunakan
System.TypeCode
danSystem.Convert
.Sangat mudah untuk membuat serial apa pun jenis yang dipetakan ke
System.TypeCode
selainSystem.TypeCode.Object
, jadi Anda bisa melakukan:Keuntungan dari pendekatan ini adalah Anda tidak perlu menyebutkan setiap tipe non-primitif lainnya yang dapat diterima. Anda juga dapat memodifikasi kode di atas sedikit untuk menangani semua jenis yang mengimplementasikan IConvertible.
sumber
Guid
untuk keperluan saya sendiri (sebagai primitif dalam definisi saya).Kami melakukannya seperti ini di ORM kami:
Saya tahu bahwa menggunakan
IsValueType
bukanlah pilihan terbaik (Anda dapat memiliki struct Anda sendiri yang sangat kompleks) tetapi berfungsi dalam 99% kasus (dan termasuk Nullables).sumber
decimal
dalam hal itu. Tetapi apakah ada tipe yangIsPrimitive
pengembaliantrue
tetapiIsValueType
pengembalianfalse
? Jika tidak ada tipe seperti itu makat.IsPrimitive
tes tidak perlu.IsValueType
disetel ke true, jadi memeriksaIsPrimitive
tidak diperlukan. Bersulang!Dari tanggapan @Ronnie Overby dan komentar @jonathanconway, saya menulis metode ini yang berfungsi untuk Nullable, dan mengecualikan struct pengguna.
Dengan TestCase berikut:
sumber
Enum
tidak didukung, uji denganenum MyEnum { EnumValue }
dan gunakanMyEnum
. @ Jonathan juga menggunakantype.IsValueType
. Dengan ituEnums
terdeteksi dengan benar, tetapi jugaStructs
. Jadi hati-hati dengan primitif apa yang Anda inginkan.type.IsValueType
, mengapa tidak menambahkantype.IsEnum
?type.IsEnum
itu juga mungkin. Saya telah menyarankan edit pada posting Anda :)Begini cara saya melakukannya.
sumber
IsAssignableFrom
dalam pengujian Anda alih-alih mengandung?Juga kemungkinan yang baik:
sumber
Type
memiliki properti yang disebut IsPrimitive . Anda harus menggunakannya sebagai gantinya.String
atauDecimal
yang primitif.Dengan asumsi Anda memiliki tanda tangan fungsi seperti ini:
Anda bisa menambahkan batasan umum untuk mengizinkan hanya tipe nilai:
Perhatikan bahwa ini memungkinkan tidak hanya tipe primitif untuk T, tetapi semua tipe nilai.
sumber
Saya memiliki kebutuhan untuk membuat cerita bersambung jenis untuk tujuan mengekspornya ke XML. Untuk melakukan ini, saya mengulangi melalui objek dan memilih bidang yang primitif, enum, tipe nilai atau serializable. Ini adalah hasil dari permintaan saya:
Saya menggunakan LINQ untuk beralih melalui tipe, kemudian mendapatkan nama dan nilai mereka untuk disimpan dalam tabel simbol. Kuncinya ada pada klausa 'di mana' yang saya pilih untuk refleksi. Saya memilih tipe nilai primitif, enumerasi, dan tipe serial. Ini memungkinkan untuk string dan objek DateTime untuk datang seperti yang saya harapkan.
Bersulang!
sumber
Ini yang saya miliki di perpustakaan saya. Komentar diterima.
Saya memeriksa IsValueType terlebih dahulu, karena menangani sebagian besar jenis, lalu String, karena ini yang paling umum kedua. Saya tidak bisa memikirkan primitif yang bukan tipe nilai, jadi saya tidak tahu apakah kaki itu pernah terkena.
Maka saya bisa menggunakannya seperti ini:
sumber
Saya hanya ingin membagikan solusi saya. Mungkin bermanfaat bagi siapa pun.
sumber
IsPrimitiveType(typeof(System.AccessViolationException)) == true
namespace System { class MyNonPrimitiveType { } }
Jangan lupa untuk memeriksa NULL namespace, karena objek anonim tidak memiliki namespace yang ditetapkan
sumber
Berikut adalah opsi lain yang layak.
sumber