Mai mult
Cum de a crea un obiect nou exemplu de la un Tip
Nimeni nu poate ști întotdeauna " Tip "de un obiect la compilare, dar ar putea avea nevoie pentru a crea un exemplu de "Tip". Cum puteți obține un obiect nou exemplu de la un "Tip"?
689
12
Anii `Activator clasa în rădăcina "Sistem" spațiu de nume este destul de puternic.
Există o mulțime de suprasarcini pentru transmiterea parametrilor către constructor și astfel. A verifica afară de documentația la:
sau (drum nou)
Aici sunt câteva exemple simple:
Anii `Activator clasa are un generic varianta care face acest lucru un pic mai ușor:
Compilate de exprimare este cel mai bun mod! (pentru performanță să creați în mod repetat instanță în execuție).
Statistică (2012):
Statistică (2015, .net 4.5, x64):
Statistică (2015, .net 4.5, x86):
Statistică (2017, LINQPad 5.22.02/x64/.NET 4.6):
Statistică (2019, x64/.NET 4.8):
Statistică (2019, x64/.NET Core 3.0):
Cod complet:
O implementare a acestei probleme este de a încerca pentru a apela parametru-mai puțin constructor de Tip:
Aici este aceeași abordare, conținute într-o metodă generică:
Ei destul de simplu. Presupunem că classname este "Auto" și spațiul de nume este "Vehicule", apoi trece parametru ca `Vehicule.Mașina care returnează obiectul de tip "Auto". Astfel puteți crea orice instanță de orice clasă dinamic.
Dacă Complet Calificat Nume(de exemplu, Vehiculele.Car
în acest caz) este într-o altă adunare,
Tip.GetType` va fi nul. În astfel de cazuri, trebuie bucla prin toate adunările și pentru a găsi "Tip". Pentru asta puteți folosi codul de mai josȘi puteți obține de exemplu prin apelarea la metoda de mai sus.
Dacă acest lucru este ceva care va fi numit o mulțime într-o aplicație exemplu,'s mult mai repede pentru a compila și dinamic cache de cod în loc de a folosi activator sau
ConstructorInfo.Invoke()
. Două opțiuni ușor pentru compilarea dinamică sunt compilate Linq Expresii sau ceva simpluIL
opcodes șiDynamicMethod
. Oricum, diferența este foarte mare atunci când începi să intri în bucle strânse sau mai multe apeluri.Dacă doriți să utilizați constructorul implicit atunci soluția folosind Sistemul.Activator
prezentate anterior este, probabil, cel mai convenabil. Cu toate acestea, în cazul în care tipul nu are un constructor implicit sau trebuie să utilizați un non-default una, apoi o opțiune este de a utiliza reflecție sau Sistem.ComponentModel.TypeDescriptor
. În caz de reflecție, este suficient să știi doar nume de tip (cu nume).De exemplu, folosind reflecție:
Exemplu, folosind
TypeDescriptor
:Nu't generic `T t = new T (); munca?
Fără utilizarea de Reflecție:
Având în vedere această problemă Activator va funcționa atunci când există o parameterless ctor. Dacă aceasta este o constrângere ia în considerare utilizarea
Eu poate peste această întrebare pentru că am fost în căutarea de a pune în aplicare un simplu CloneObject metodă pentru arbitrară de clasă (cu un constructor implicit)
Cu metodă generică puteți solicita ca tipul implementează Noi().
Cu non-generice-și asume tip are un constructor implicit și prinde o excepție în cazul în care nu't.