Seseorang mungkin tidak selalu mengetahui Type
objek pada saat kompilasi, tetapi mungkin perlu membuat instance dari Type
.
Bagaimana Anda mendapatkan instance objek baru dari Type
?
c#
.net
performance
reflection
types
tags2k
sumber
sumber
ObjectType instance
cocok dengan kondisi OP "Seseorang mungkin tidak selalu tahu jenis objek pada waktu kompilasi"? : Pobject instance = Activator.CreateInstance(...);
,.The
Activator
kelas memiliki varian generik yang membuat ini sedikit lebih mudah:sumber
dynamic
konstruk yang memang mengizinkan konstruk tersebut tetapi untuk sebagian besar tujuan jawaban ini masih mencakupnya.Ekspresi terkompilasi adalah cara terbaik! (agar kinerja berulang kali membuat instance dalam runtime).
Statistik (2012):
Statistik (2015, .net 4.5, x64):
Statistik (2015, .net 4.5, x86):
Statistik (2017, LINQPad 5.22.02 / x64 / .NET 4.6):
Statistik (2019, x64 / .NET 4.8):
Statistik (2019, x64 / .NET Core 3.0):
Kode lengkap:
sumber
X
saat runtime?Type
.Salah satu implementasi dari masalah ini adalah mencoba memanggil konstruktor tanpa parameter dari Tipe:
Berikut adalah pendekatan yang sama, terkandung dalam metode generik:
sumber
Cukup sederhana. Asumsikan bahwa nama kelas Anda
Car
dan namespace adalahVehicles
, lalu kirimkan parameterVehicles.Car
yang mengembalikan objek bertipeCar
. Seperti ini, Anda dapat membuat instance kelas apa pun secara dinamis.Jika Nama Sepenuhnya Memenuhi Syarat Anda (yaitu,
Vehicles.Car
dalam hal ini) di majelis lain, ituType.GetType
akan menjadi nol. Dalam kasus seperti itu, Anda memiliki perulangan melalui semua majelis dan menemukanType
. Untuk itu Anda bisa menggunakan kode di bawah iniDan Anda bisa mendapatkan instance dengan memanggil metode di atas.
sumber
Jika ini untuk sesuatu yang akan disebut banyak dalam contoh aplikasi, itu jauh lebih cepat untuk mengkompilasi dan menyimpan kode dinamis daripada menggunakan aktivator atau
ConstructorInfo.Invoke()
. Dua opsi mudah untuk kompilasi dinamis dikompilasi dengan Linq Expressions atau beberapaIL
opcodeDynamicMethod
sederhana dan . Either way, perbedaannya sangat besar ketika Anda mulai masuk ke loop ketat atau beberapa panggilan.sumber
Bukankah generiknya
T t = new T();
berfungsi?sumber
Jika Anda ingin menggunakan konstruktor default maka solusi menggunakan yang
System.Activator
disajikan sebelumnya mungkin yang paling nyaman. Namun, jika jenis tidak memiliki konstruktor default atau Anda harus menggunakan yang non-default, maka opsi adalah menggunakan refleksi atauSystem.ComponentModel.TypeDescriptor
. Dalam hal refleksi, cukup untuk mengetahui hanya nama tipe (dengan namespace-nya).Contoh menggunakan refleksi:
Contoh menggunakan
TypeDescriptor
:sumber
args[]
persis apa yang saya datang ke pertanyaan ini untuk menemukan, terima kasih!Tanpa menggunakan Refleksi:
sumber
Dengan masalah ini, Activator akan bekerja ketika ada parameter tanpa parameter. Jika ini merupakan kendala, pertimbangkan untuk menggunakan
sumber
sumber
Saya dapat menemukan pertanyaan ini karena saya ingin menerapkan metode CloneObject sederhana untuk kelas arbitrer (dengan konstruktor default)
Dengan metode generik Anda dapat meminta jenis mengimplementasikan New ().
Dengan non-generik anggap jenis memiliki konstruktor default dan menangkap pengecualian jika tidak.
sumber