Type.GetType (“namespace.abClassName”) null değerini döndürür


216

Bu kod:

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

döner null.

ve ben kullanıcılarda var:

using namespace.a.b;

Güncelleme:

Tür var, farklı bir sınıf kitaplığında ve ben dize adı ile almak gerekir.


Derleme nitelikli adının nasıl alınacağı hakkında bilgi için bu stackoverflow.com/questions/441680/… adresine bakın .
Polyfun

Yanıtlar:


244

Type.GetType("namespace.qualified.TypeName") yalnızca tür mscorlib.dll veya o anda yürütülmekte olan derlemede bulunduğunda çalışır.

Bunlardan hiçbiri doğru değilse, derlemeye uygun bir ada ihtiyacınız olacaktır :

Type.GetType("namespace.qualified.TypeName, Assembly.Name")

3
türü var, farklı bir sınıf kitaplığında, ve ben dize adı ile almak gerekir
Omu

25
Derlemeye uygun bir ad kullanmak yerine derlemeyi ada göre yükleyebilir - Assembly a = Assembly.Load("SomeLibrary");- ve sonra derlemeyi adından türüne yükleyebilirsiniz - Type t = a.GetType("namespace.a.b.ClassName");.
Kenny Evitt

6
Belki de typeof(SomeTypeInThatAssembly).Assembly.GetTypes().Where((t) => t.FullName == youFullName);sonuçta biraz güçlük çekebilirsiniz
Felype

Felype'ın yanıtı çalışabildiğim tek yanıttı.
Rudy Scoggins

@Felype yorum için .FirstOrDefault () ekle
Leandro

173

Tür derleme nitelikli adı olmadan, ancak dll adı ile de alabilirsiniz, örneğin:

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

Aynı durum vardı ve benim için çalıştı. "DataModel.QueueObject" türünde bir nesneye ihtiyacım vardı ve aşağıdaki gibi türü var "DataModel" için bir başvuru vardı:

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

Virgülden sonraki ikinci dize referans adıdır (dll adı).


2
Bu bir 'hile' mi yoksa gerçek bir yöntem mi? Bunu -_- belgelerinde bulamıyorum. Bu arada, benim 1 hafta acı biter! teşekkürler
DnR

1
Bu çok daha temiz bir çözüm, bu nedenle herhangi bir tuzak olup olmadığını görmek isterim.
cossacksman

4
Bu cevapta kullanılan form , MSDN dilbilgisine göre tam nitelikli bir tür adıdır (bu nedenle bir hile değildir ). Şeklidir NamespaceTypeName, AssemblyNameSpecburada AssemblyNameSpecherhangi bir özelliği olmayan düzeneğin tanımlayıcısıdır. Bu cevap temelde aynı olsa da bunun toplanma özellikleri tanıtmak olduğunu "gürültü" (örneğin bazı ortadan kaldıran, çünkü bazı insanlar bu tercih farz kabul olarak Version, Culture PublicKeyToken). Neyse ki, özellikler isteğe bağlıdır .
Martin Liversage

Yuvalanmış türler için, şöyle bir şey yapmanız gerekebilirAtlasKernelBusinessModel.AtlasConstants+ClaimCoverage+Status,AtlasKernelBusinessModel
toddmo

Teşekkürler, App_Code klasörü için çalışır. Örnek: Type.GetType ("TypeName, App_Code");
Burak Koray Balcı

79

bu yöntemi kullanmayı dene

 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 ;
        }

Aslında bu benim için işe yaradı. Ben derleme döngü önce bir alt dize kırpma ekleyerek tweak gerekiyordu, ancak, derleme nitelikli bir ad geçti ve Assembly.GetType () yalnızca derleme bilgileri hariç tutarsanız çalışır.
Colin

bu harika görünüyor, ama diğer montaj türlerini kullanan jenerikler ne olacak?
Demetris Leptos

AppDomainDesteklenmediği için UWP için çalışmıyor . Alternatiflerden emin değilim.
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;
}

1
bu harika görünüyor, ama diğer montaj türlerini kullanan jenerikler ne olacak?
Demetris Leptos

1
@DemetrisLeptos (Yorumun eski olduğunu biliyorum - ancak diğer insanlar hala ilgilenebilir): int dizinini kullan = typeName.IndexOf ('``); if (dizin> 0) {typeName = _typeName.Substring (0, dizin + 2); } TGenel türün kaldırıldığını unutmayın.
Bernhard Hiller

25

Derleme bir ASP.NET uygulaması derlemesinin bir parçasıysa, BuildManager sınıfını kullanabilirsiniz:

using System.Web.Compilation
...
BuildManager.GetType(typeName, false);

1
Bu harika bir cevap ve sayfada daha yüksek olması gerekiyor. Bir cazibe gibi çalışır ve montajın nitelikli tür adını almanın eski yoluna kıyasla çok basit.
Graham

bu inanılmaz basit ve nokta, yansıma nesnelerinin performans optimizasyonu ile bana yardımcı olabilir misiniz?
Alok

15

sınıfınız geçerli olarak mevcut değilse nitelikliName vermelisiniz ve bu kod sınıfın nitelikli adını nasıl alacağınızı gösterir

string qualifiedName = typeof(YourClass).AssemblyQualifiedName;

ve daha sonra nitelikliName ile yazabilirsiniz

Type elementType = Type.GetType(qualifiedName);

8

Yuvalanmış bir Türse, a'yı dönüştürmeyi unutmuş olabilirsiniz. + 'ya

Ne olursa olsun, typeof( T).FullNamesize ne söylemeniz gerektiğini söyleyecek

DÜZENLEME: BTW (bildiğiniz gibi emin) kullanımı derleyici yalnızca derleme yönergeleri vardır ve bu nedenle API çağrısının başarısı üzerinde herhangi bir etkisi olamaz. (Potansiyel olarak etkisi olabilecek proje veya montaj referanslarınız varsa - bu nedenle bilgi işe yaramaz, sadece bazı filtreleme gerektirir ...)


Aman! Bu "+" - sözdiziminin nerede açıklandığını biliyor musunuz?
Koruyucu bir

1
Protectorone Bunu amazon.com/Essential-NET-Common-Language-Runtime/dp/0201734117 IIRC adresinden öğrendim , ancak bu biraz tarihli. Amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/… ' ı tüm .NET geliştiricileri için tartışmasız faydalı bir kitap olarak önerebilir miyim ? Alt satırda, Türler için, CLR'nin yalnızca ad alanı ve adı vardır - iç içe bir tür doğrudan adreslenemez. Bu nedenle, bir dil, iç içe geçmiş bir kavramı varsa, ihtiyaç duyduğu şeyi yapar (genel olarak çoğu +
şerit

6

Kullanıcının veritabanında belirtilen kullanıcı denetimine bağlı olarak kullanıcı denetimlerini açıyorum. Bu yüzden TypeName almak için bu yöntemi kullandım ...

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

Böylece, bu nesnenin bir örneğini oluşturmak için strType'ta döndürülen değer kullanılabilir.


destansı bir konuyu yeniden açmak ... tebrikler. Ancak TO'nun Typename'i bildiği ve türünü ondan almak istediğinden cevabınızı küçümsemeliyim. Btw .: Type.GetType yalnızca geçerli yürütme derlemenizde veya mscorlib içinde olan türlerde çalışır, ancak TO sais yok olarak <c> GetType (Namespace.ClassName) </c> ile hangi yönteme başvuruyorsunuz? bu koşullar geçerlidir.
HimBromBeere

2
@HimBromBeere Aşağı oy için teşekkürler. Bulgularımı göndermem için beni motive eden sizin gibi insanlar. Hala gelişmeyi öğreniyorum ve sadece başkalarına yardım etmeye çalışıyorum. Şimdi sorunuzu cevaplamamı mı bekliyorsunuz? Bu arada, soruyu doğru cevapladım. Bir örnek oluşturduğum sınıf farklı bir projede bulunuyor ve bu yüzden bir AssemblyQualified adı kullanmak zorunda. Bu yüzden lütfen indirmeden önce geri kalan yorumları okuyun. "türü var, farklı bir sınıf kütüphanesinde ve ben dize adı - Omu ile almak gerekir"
Stephan

6

Ben sadece sınıf adı var bunu kullanın:

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

5

As Type.GetType (String) ihtiyaç Type.AssemblyQualifiedName kullanmanız gereken 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);

Sürüm, Kültür ve PublicKeyToken aşağıdakiler için gerekli değildir assemblyName nedenle MyAssembly.GetName () işlevini kullanabilmeniz .

Hakkında Type.GetType (dize) :

Tür, şu anda yürütülen derlemede veya Mscorlib.dll dosyasındaysa, ad alanı tarafından nitelenen tür adını sağlamak yeterlidir.


4

Derlemeye başvurulursa ve Sınıf görünürse:

typeof(namespace.a.b.ClassName)

Tür bulunamadığı için GetType null döndürür, typeof ile derleyici hatayı bulmanıza yardımcı olabilir.


türü var, farklı bir sınıf kütüphanesinde, ve ben dize adı ile almak gerekir
Omu

4

Montaj bilgilerini içeren tam tür adını kullanmayı deneyin, örneğin:

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

Ben sadece namesspace.classname farklı bir derleme sınıf türünü almak için kullanırken aynı durum vardı ve işe yaramaz. Yalnızca yukarıda gösterildiği gibi tip dizgime montaj bilgilerini eklediğimde çalıştı.


3

Virgülün tam olarak nitelenmiş addan hemen sonra olduğundan emin olun

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

Bu işe yaramayacağı için

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

Bu bir kaç gündür güldüm


2

Benim için anahtar "+" idi! Bu benim sınıfım (iç içe geçmiş):

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

ve bu kod satırı işe yaradı:

Type type = Type.GetType("PortalServices.PortalManagement+Merchant");

1

Yukarıdaki bu çözüm benim için en iyisi gibi görünüyor, ama benim için işe yaramadı, bu yüzden aşağıdaki gibi yaptım:

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

Type myType = Type.GetType(typeAssemblyQualifiedName);

Önkoşul, montajın yolunu bilmenizdir. Benim durumumda bunu biliyorum, çünkü bu başka bir dahili projeden yapılmış bir derleme ve projemizin bin klasörüne dahil.

Önemli olması durumunda Visual Studio 2013 kullanıyorum, hedef .NET 4.0. Bu bir ASP.NET projesidir, bu yüzden mutlak yol alıyorum HttpContext. Ancak, AssemblyQualifiedNames üzerindeki MSDN'den göründüğü gibi, mutlak yol bir zorunluluk değildir


0

Ben aldattım. Ben oluşturmak istediğiniz türleri (ada göre) hepsi bir dll ı denetiminde olduğundan, ben sadece basit bir ad alır derleme dll statik bir yöntem koymak ve bu bağlamdan type.GetType çağırır ve sonuç döndürür .

Orijinal amaç, türün yapılandırma verilerinde adla belirtilebilmesiydi. Ben beri kullanıcı işlemek için bir biçim belirtilen şekilde kodu değiştirmek ettik. Biçim işleyici sınıfları, türün belirtilen biçimi ayrışıp ayrıştıramayacağını belirleyen bir arabirim uygular. Daha sonra arabirimi uygulayan türleri bulmak ve yansımayı işleyen bir biçim bulmak için yansıma kullanın. Şimdi yapılandırma belirli bir tür değil, bir biçim adı belirtir. Yansıma kodu bitişik dll ve yük bakabilirsiniz, bu yüzden ben bir tür kötü adamın eklenti mimarisi var.


Merhaba, yanlışlıkla indirdim, lütfen cevabınızı düzenleyin, böylece geri alabilirim.
coloboxp
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.