Type.GetType ("namespace.abClassName") mengembalikan nol

216

Kode ini:

Type.GetType("namespace.a.b.ClassName")

kembali null.

dan saya miliki dalam usings:

using namespace.a.b;

Memperbarui:

Jenisnya ada, ada di pustaka kelas yang berbeda, dan saya perlu mendapatkannya dengan nama string.

Omu
sumber
Lihat stackoverflow.com/questions/441680/… ini untuk info tentang cara mendapatkan nama yang memenuhi syarat perakitan.
Polyfun

Jawaban:

244

Type.GetType("namespace.qualified.TypeName") hanya berfungsi ketika jenisnya ditemukan di mscorlib.dll atau majelis yang sedang dieksekusi.

Jika tidak satu pun dari hal-hal itu benar, Anda memerlukan nama yang memenuhi syarat perakitan :

Type.GetType("namespace.qualified.TypeName, Assembly.Name")
DrPizza
sumber
3
jenis ada, itu di perpustakaan kelas yang berbeda, dan saya perlu untuk mendapatkannya dengan nama string yang
Omu
25
Alih-alih menggunakan nama yang memenuhi syarat rakitan, Anda dapat memuat rakitan dengan nama - Assembly a = Assembly.Load("SomeLibrary");- dan kemudian memuat jenis berdasarkan nama dari rakitan - Type t = a.GetType("namespace.a.b.ClassName");.
Kenny Evitt
6
Mungkin Anda bisa suka typeof(SomeTypeInThatAssembly).Assembly.GetTypes().Where((t) => t.FullName == youFullName);mungkin menyimpan sedikit kerumitan, akhirnya
Felype
Tanggapan Felype adalah satu-satunya yang dapat saya kerjakan.
Rudy Scoggins
Tambahkan .FirstOrDefault () ke komentar @Felype
Leandro
173

Anda juga bisa mendapatkan jenis tanpa nama yang memenuhi syarat perakitan tetapi dengan nama dll juga, misalnya:

Type myClassType = Type.GetType("TypeName,DllName");

Saya memiliki situasi yang sama dan itu berhasil untuk saya. Saya membutuhkan objek tipe "DataModel.QueueObject" dan memiliki referensi ke "DataModel" jadi saya mendapatkan tipe sebagai berikut:

Type type = Type.GetType("DataModel.QueueObject,DataModel");

String kedua setelah koma adalah nama referensi (nama dll).

Asaf Pala
sumber
2
Apakah ini 'trik' atau metode aktual? Saya tidak dapat menemukan ini di dokumentasi -_-. Ngomong-ngomong, itu berakhir 1 minggu saya menderita! terima kasih
DNR
1
Ini adalah solusi yang jauh lebih bersih, saya ingin melihat apakah ada jebakan karena ini.
cossackman
4
Formulir yang digunakan dalam jawaban ini juga merupakan nama jenis yang sepenuhnya memenuhi syarat menurut tata bahasa MSDN (jadi itu bukan tipuan ). Formulir adalah NamespaceTypeName, AssemblyNameSpectempat AssemblyNameSpecpengenal dari rakitan tanpa properti apa pun. Meskipun jawaban ini pada dasarnya sama dengan yang diterima saya berasumsi bahwa beberapa orang lebih suka ini karena tidak jauh dengan beberapa "kebisingan" yang diperkenalkan oleh properti rakitan (misalnya Version, Culture PublicKeyToken). Untungnya, propertinya opsional .
Martin Liversage
Untuk tipe bersarang, Anda mungkin perlu melakukan sesuatu sepertiAtlasKernelBusinessModel.AtlasConstants+ClaimCoverage+Status,AtlasKernelBusinessModel
toddmo
Terima kasih, ini berfungsi untuk folder App_Code. Contoh: Type.GetType ("TypeName, App_Code");
Burak Koray Balcı
79

coba gunakan metode ini

 public static Type GetType(string typeName)
        {
            var type = Type.GetType(typeName);
            if (type != null) return type;
            foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
            {
                type = a.GetType(typeName);
                if (type != null)
                    return type;
            }
            return null ;
        }
peyman
sumber
Inilah yang sebenarnya bekerja untuk saya. Saya harus men-tweak dengan menambahkan trim substring sebelum loop foreach, karena saya lulus dalam nama yang memenuhi syarat perakitan, dan Assembly.GetType () hanya berfungsi jika Anda mengecualikan informasi perakitan.
Colin
ini terlihat hebat, tetapi bagaimana dengan obat generik yang menggunakan jenis perakitan lain?
Demetris Leptos
Tidak berfungsi untuk UWP karena AppDomaintidak didukung. Tidak yakin ada alternatif.
James M
25
Dictionary<string, Type> typeCache;
...
public static bool TryFindType(string typeName, out Type t) {
    lock (typeCache) {
        if (!typeCache.TryGetValue(typeName, out t)) {
            foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
                t = a.GetType(typeName);
                if (t != null)
                    break;
            }
            typeCache[typeName] = t; // perhaps null
        }
    }
    return t != null;
}
erikkallen
sumber
1
ini terlihat hebat, tetapi bagaimana dengan obat generik yang menggunakan jenis perakitan lain?
Demetris Leptos
1
@DemetrisLeptos (saya tahu komentarnya sudah lama - tetapi orang lain mungkin masih tertarik): gunakan int index = typeName.IndexOf ('`'); if (index> 0) {typeName = _typeName.Substring (0, index + 2); } Perhatikan bahwa Ttipe generik dilucuti.
Bernhard Hiller
25

Jika perakitan adalah bagian dari pembuatan aplikasi ASP.NET, Anda bisa menggunakan kelas BuildManager:

using System.Web.Compilation
...
BuildManager.GetType(typeName, false);
LarryBud
sumber
1
Ini adalah jawaban yang fantastis dan harus lebih tinggi di halaman. Bekerja seperti pesona dan sangat sederhana dibandingkan dengan cara lama mendapatkan nama tipe yang memenuhi syarat perakitan.
Graham
ini luar biasa sederhana dan tepat, dapatkah Anda membantu saya dengan optimalisasi kinerja objek refleksi?
Alok
15

jika kelas Anda tidak ada dalam assambly saat ini Anda harus memberikan kualifikasiNama dan kode ini menunjukkan cara untuk mendapatkan kualifikasinama kelas

string qualifiedName = typeof(YourClass).AssemblyQualifiedName;

dan kemudian Anda bisa mendapatkan tipe dengan kualifikasiNama

Type elementType = Type.GetType(qualifiedName);
Numan KIZILIRMAK
sumber
8

Jika ini adalah Tipe bersarang, Anda mungkin lupa untuk mengubah a. ke +

Bagaimanapun, typeof( T).FullNameakan memberi tahu Anda apa yang seharusnya Anda katakan

EDIT: BTW usings (seperti yang saya yakin Anda tahu) hanya arahan ke kompiler pada waktu kompilasi dan dengan demikian tidak dapat memiliki dampak pada keberhasilan panggilan API. (Jika Anda memiliki referensi proyek atau perakitan, yang berpotensi memiliki pengaruh - maka informasinya tidak berguna, hanya perlu beberapa penyaringan ...)

Ruben Bartelink
sumber
Astaga! Apakah Anda tahu di mana "+" ini - sintaks dijelaskan?
Pelindung satu
1
Protectorone Saya mempelajarinya dari amazon.com/Essential-NET-Common-Language-Runtime/dp/0201734117 IIRC, tapi itu agak ketinggalan zaman. Dapatkah saya merekomendasikan amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/… sebagai buku yang sangat berguna untuk semua. NET devs + termasuk ini? Intinya adalah bahwa untuk Jenis, CLR hanya memiliki namespace dan nama - tipe bersarang tidak langsung dialamatkan. Oleh karena itu bahasa, jika memiliki konsep tipe bersarang akan melakukan apa yang dibutuhkannya (meskipun secara umum sebagian besar komputer menggunakan +pemisah)
Ruben Bartelink
6

Saya membuka kontrol pengguna tergantung pada apa yang mengontrol pengguna memiliki akses ke ditentukan dalam database. Jadi saya menggunakan metode ini untuk mendapatkan TypeName ...

Dim strType As String = GetType(Namespace.ClassName).AssemblyQualifiedName.ToString
Dim obj As UserControl = Activator.CreateInstance(Type.GetType(strType))

Jadi sekarang kita dapat menggunakan nilai yang dikembalikan dalam strType untuk membuat turunan dari objek itu.

Stephan
sumber
membuka kembali topik epik-tua ... selamat. Namun saya harus menurunkan jawaban Anda karena TO benar-benar mengetahui Typename dan ingin mendapatkan tipenya. Btw .: metode mana yang Anda referensikan dengan <c> GetType (Namespace.ClassName) </c>, jika Type.GetType itu hanya akan bekerja pada jenis yang ada di dalam rakitan pelaksana Anda saat ini atau mscorlib, tetapi sebagai TO sais none ketentuan ini berlaku.
HimBromBeere
2
@HimBromBeere Terima kasih atas suaranya. Orang-orang seperti Anda yang mendemotivasi saya untuk mengirim temuan saya. Saya masih belajar pengembangan dan saya hanya berusaha membantu orang lain. Dan sekarang Anda mengharapkan saya untuk menjawab pertanyaan Anda? Omong-omong, saya telah menjawab pertanyaan dengan benar. Kelas yang saya buat contoh berada di proyek yang berbeda dan seseorang harus menggunakan nama AssemblyQualified karena itu. Jadi silakan baca sisa komentar sebelum downvoting. "Jenisnya ada, ada di perpustakaan kelas yang berbeda, dan saya perlu mendapatkannya dengan nama string - Omu"
Stephan
6

Ketika saya hanya memiliki nama kelas, saya menggunakan ini:

Type obj = AppDomain.CurrentDomain.GetAssemblies().SelectMany(t => t.GetTypes()).Where(t => String.Equals(t.Name, _viewModelName, StringComparison.Ordinal)).First();
Marchino
sumber
5

Sebagai Type.GetType (String) membutuhkan Type.AssemblyQualifiedName, Anda harus menggunakan Assembly.CreateQualifiedName (String, String) .

string typeName = "MyNamespace.MyClass"; // Type.FullName
string assemblyName = "MyAssemblyName"; // MyAssembly.FullName or MyAssembly.GetName().Name
string assemblyQualifiedName = Assembly.CreateQualifiedName(assemblyName , typeName);
Type myClassType = Type.GetType(assemblyQualifiedName);

Versi, Budaya, dan PublicKeyToken tidak diperlukan karena assemblyNameitu Anda dapat menggunakan MyAssembly.GetName (). Name.

Tentang Type.GetType (String) :

Jika jenisnya ada di majelis yang sedang dieksekusi atau di Mscorlib.dll, cukup untuk memberikan nama jenis yang memenuhi syarat oleh namespace-nya.

Florian Talour
sumber
4

Jika perakitan direferensikan dan Kelas terlihat:

typeof(namespace.a.b.ClassName)

GetType mengembalikan nol karena jenisnya tidak ditemukan, dengan typeof, kompiler dapat membantu Anda untuk menemukan kesalahan.

Guillaume
sumber
jenis ada, itu di perpustakaan kelas yang berbeda, dan saya perlu untuk mendapatkannya dengan nama string yang
Omu
4

Coba gunakan nama tipe lengkap yang menyertakan info rakitan, misalnya:

string typeName = @"MyCompany.MyApp.MyDomain.MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
Type myClassType = Type.GetType(typeName);

Saya memiliki situasi yang sama ketika saya hanya menggunakan namesspace.classname untuk mendapatkan jenis kelas di majelis yang berbeda dan itu tidak akan berhasil. Hanya berfungsi ketika saya menyertakan info perakitan dalam string tipe saya seperti yang ditunjukkan di atas.

Ismail Hawayel
sumber
3

Pastikan koma tepat setelah nama yang memenuhi syarat

typeof(namespace.a.b.ClassName, AssemblyName)

Karena ini tidak akan berhasil

typeof(namespace.a.b.ClassName ,AssemblyName)

Saya buntung selama beberapa hari untuk hal ini

jack_tux
sumber
2

Bagi saya, "+" adalah kuncinya! Ini kelas saya (ini kelas bersarang):

namespace PortalServices
{
public class PortalManagement : WebService
{
    public class Merchant
    {}
}
}

dan baris kode ini berfungsi:

Type type = Type.GetType("PortalServices.PortalManagement+Merchant");
Arash Masir
sumber
1

Ini solusi atas tampaknya menjadi yang terbaik untuk saya, tapi itu tidak bekerja untuk saya, jadi saya melakukannya sebagai berikut:

AssemblyName assemblyName = AssemblyName.GetAssemblyName(HttpContext.Current.Server.MapPath("~\\Bin\\AnotherAssembly.dll"));
string typeAssemblyQualifiedName = string.Join(", ", "MyNamespace.MyType", assemblyName.FullName);

Type myType = Type.GetType(typeAssemblyQualifiedName);

Prasyaratnya adalah Anda mengetahui jalur perakitan. Dalam kasus saya, saya tahu itu karena ini adalah perakitan yang dibangun dari proyek internal lain dan termasuk dalam folder bin proyek kami.

Jika saya menggunakan Visual Studio 2013, target saya .NET adalah 4.0. Ini adalah proyek ASP.NET, jadi saya mendapatkan jalur absolut melalui HttpContext. Namun, jalur absolut bukan persyaratan seperti yang terlihat dari MSDN di AssemblyQualifiedNames

Ozair Kafray
sumber
0

Aku curang. Karena tipe yang ingin saya buat (dengan nama) semuanya ada di dalam kontrol I dll, saya hanya meletakkan metode statis di dll dalam rakitan yang mengambil nama sederhana, dan memanggil tipe. Dapatkan tipe dari konteks itu dan mengembalikan hasilnya .

Tujuan aslinya adalah agar tipe dapat ditentukan oleh nama dalam data konfigurasi. Saya telah mengubah kode sehingga pengguna menentukan format untuk diproses. Kelas penangan format mengimplementasikan antarmuka yang menentukan apakah tipe dapat mem-parsing format yang ditentukan. Saya kemudian menggunakan refleksi untuk menemukan tipe yang mengimplementasikan antarmuka, dan menemukan tipe yang menangani format. Jadi sekarang konfigurasi menentukan nama format, bukan tipe tertentu. Kode refleksi dapat melihat dll yang berdekatan dan memuat, mereka jadi saya punya semacam arsitektur plug-in orang miskin.

Darrel Lee
sumber
Hai, saya telah dibatalkan karena kesalahan, harap edit balasan Anda sehingga saya dapat membatalkannya.
coloboxp