Type.GetType („namespace.abClassName”) zwraca null


216

Ten kod:

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

zwraca null.

i mam w użyciu:

using namespace.a.b;

Aktualizacja:

Ten typ istnieje, jest w innej bibliotece klas i muszę go zdobyć po nazwie łańcucha.


Zobacz to stackoverflow.com/questions/441680/ ..., aby uzyskać informacje na temat uzyskiwania kwalifikowanej nazwy zestawu.
Polyfun,

Odpowiedzi:


244

Type.GetType("namespace.qualified.TypeName") działa tylko wtedy, gdy typ zostanie znaleziony w pliku mscorlib.dll lub aktualnie wykonywanym zestawie.

Jeśli żadna z tych rzeczy nie jest prawdą, potrzebujesz nazwy kwalifikującej się do złożenia :

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

3
typ istnieje, jest w innej bibliotece klas i muszę go pobrać według nazwy łańcucha
Omu

25
Zamiast używać nazwy kwalifikowanej dla zestawu, można załadować zestaw według nazwy - Assembly a = Assembly.Load("SomeLibrary");- a następnie załadować typ według nazwy z zestawu - Type t = a.GetType("namespace.a.b.ClassName");.
Kenny Evitt,

6
Być może może chcesz typeof(SomeTypeInThatAssembly).Assembly.GetTypes().Where((t) => t.FullName == youFullName);zaoszczędzić trochę kłopotów, w końcu
Felype,

Odpowiedź Felype była jedyną, jaką mogłem uruchomić.
Rudy Scoggins,

Dodaj .FirstOrDefault () do komentarza @Felype
Leandro

173

Możesz także uzyskać typ bez nazwy kwalifikowanej dla zestawu, ale z nazwą dll również, na przykład:

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

Miałem tę samą sytuację i zadziałało to dla mnie. Potrzebowałem obiektu typu „DataModel.QueueObject” i miałem odniesienie do „DataModel”, więc otrzymałem ten typ w następujący sposób:

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

Drugi ciąg po przecinku to nazwa odwołania (nazwa dll).


2
Czy to „sztuczka” czy faktyczna metoda? Nie mogę tego znaleźć w dokumentacji -_-. Nawiasem mówiąc, kończy się mój 1 tydzień cierpienia! dzięki
DnR

1
To jest znacznie czystsze rozwiązanie, chciałbym zobaczyć, czy z tego powodu są jakieś pułapki.
Kozak

4
Formularz użyty w tej odpowiedzi jest również w pełni kwalifikowaną nazwą typu zgodną z gramatyką MSDN (więc nie jest to sztuczka ). Formularz to NamespaceTypeName, AssemblyNameSpecgdzie AssemblyNameSpecjest identyfikator zestawu bez żadnych właściwości. Nawet jeśli ta odpowiedź jest w zasadzie taka sama jak przyjęta Przypuszczam, że niektórzy ludzie wolą to dlatego, że eliminuje niektóre z „szumu”, że właściwości montażowych wprowadzenia (np Version, Culture PublicKeyToken). Na szczęście właściwości są opcjonalne .
Martin Liversage,

W przypadku typów zagnieżdżonych może być konieczne zrobienie czegoś takiegoAtlasKernelBusinessModel.AtlasConstants+ClaimCoverage+Status,AtlasKernelBusinessModel
toddmo

Dzięki, działa z folderem App_Code. Przykład: Type.GetType („TypeName, App_Code”);
Burak Koray Balcı

79

spróbuj użyć tej metody

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

Właśnie to dla mnie zadziałało. Musiałem jednak dostosować, dodając wykończenie podłańcucha przed pętlą foreach, ponieważ przekazałem nazwę kwalifikującą się do złożenia, a Assembly.GetType () działa tylko wtedy, gdy wykluczysz informacje o zestawie.
Colin

wygląda to świetnie, ale co z rodzajami używającymi innych typów zespołów?
Demetris Leptos

Nie działa dla UWP, ponieważ AppDomainnie jest obsługiwany. Nie jestem pewien żadnych alternatyw.
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
wygląda to świetnie, ale co z rodzajami używającymi innych typów zespołów?
Demetris Leptos

1
@DemetrisLeptos (wiem, że komentarz jest stary - ale inne osoby mogą być nadal zainteresowane): użyj int index = typeName.IndexOf ('' '); if (indeks> 0) {typeName = _typeName.Substring (0, index + 2); } Zauważ, że Ttyp ogólny jest pozbawiony.
Bernhard Hiller

25

Jeśli zestaw jest częścią kompilacji aplikacji ASP.NET, możesz użyć klasy BuildManager:

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

1
To fantastyczna odpowiedź i powinna znajdować się wyżej na stronie. Działa jak urok i jest niesamowicie prosty w porównaniu ze starym sposobem uzyskiwania nazwy typu kwalifikowanego zestawu.
Graham

jest to niezwykle proste i precyzyjne, czy możesz mi pomóc w optymalizacji wydajności obiektów odbijających?
Alok

15

jeśli twojej klasy nie ma w obecnym zespole, musisz podać kwalifikowaną nazwę, a ten kod pokazuje, jak uzyskać kwalifikowaną nazwę klasy

string qualifiedName = typeof(YourClass).AssemblyQualifiedName;

i wtedy możesz uzyskać typ z kwalifikowaną nazwą

Type elementType = Type.GetType(qualifiedName);

8

Jeśli jest to typ zagnieżdżony, być może zapominasz o przekształceniu. do +

Bez względu, typeof( T).FullName powiem ci, co powinieneś powiedzieć

EDYCJA: BTW, zastosowania (jak jestem pewien, że wiesz) są tylko dyrektywami kompilatora w czasie kompilacji i dlatego nie mogą mieć żadnego wpływu na powodzenie wywołania API. (Jeśli miałeś odniesienia do projektu lub zestawu, które mogłyby potencjalnie mieć wpływ - dlatego informacja nie jest bezużyteczna, wystarczy tylko trochę filtrowania ...)


O mój! Czy wiesz, gdzie wyjaśniono tę składnię „+”?
Protektor jeden

1
Protectorone Nauczyłem się tego od amazon.com/Essential-NET-Common-Language-Runtime/dp/0201734117 IIRC, ale to trochę przestarzałe. Czy mogę polecić amazon.com/CLR-via-4th-Developer-Reference/dp/0735667454/... jako bezbłędnie przydatną książkę dla wszystkich deweloperów platformy .NET +? Najważniejsze jest to, że w przypadku typów CLR ma tylko przestrzeń nazw i nazwę - typu zagnieżdżonego nie można bezpośrednio adresować. Stąd język, jeśli ma koncepcję typu zagnieżdżonego, robi to, czego potrzebuje (choć ogólnie większość języków używa +separatora)
Ruben Bartelink

6

Otwieram kontrolki użytkownika w zależności od tego, które kontrolki użytkownik ma dostęp do określonych w bazie danych. Więc użyłem tej metody, aby uzyskać TypeName ...

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

Teraz można użyć wartości zwróconej w strType, aby utworzyć instancję tego obiektu.


ponowne otwarcie epickiego starego tematu ... gratulacje. Muszę jednak zanotować twoją odpowiedź, ponieważ TO faktycznie zna nazwę typu i chce uzyskać z niej typ. Utw. niniejszych warunków ma zastosowanie.
HimBromBeere

2
@HimBromBeere Dzięki za głos w dół. To ludzie tacy jak ty demotywują mnie do publikowania moich ustaleń. Wciąż uczę się rozwoju i staram się tylko pomagać innym. A teraz oczekujesz, że odpowiem na twoje pytanie? Nawiasem mówiąc, poprawnie odpowiedziałem na pytanie. Klasa, którą tworzyłem instancję, rezyduje w innym projekcie i z tego powodu należy użyć nazwy AssemblyQualified. Proszę przeczytać resztę komentarzy przed oddaniem głosu. „typ istnieje, znajduje się w innej bibliotece klas i muszę go zdobyć po nazwie łańcucha - Omu”
Stephan

6

Gdy mam tylko nazwę klasy, używam tego:

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

5

Ponieważ Type.GetType (String) potrzebuje Type.AssemblyQualifiedName , powinieneś użyć 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);

Wersja, kultura i klucz publiczny nie są wymagane assemblyName , dlatego możesz użyć MyAssembly.GetName (). Name.

Informacje o Type.GetType (String) :

Jeśli typ znajduje się w aktualnie wykonywanym zestawie lub w Mscorlib.dll, wystarczy podać nazwę typu kwalifikowaną przez jego przestrzeń nazw.


4

Jeśli zespół jest przywołany, a klasa widoczna:

typeof(namespace.a.b.ClassName)

GetType zwraca null, ponieważ typ nie został znaleziony, w przypadku typeof kompilator może pomóc znaleźć błąd.


typ istnieje, jest w innej bibliotece klas i muszę go pobrać według nazwy łańcucha
Omu

4

Spróbuj użyć pełnej nazwy typu, która zawiera informacje o zestawie, na przykład:

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

Miałem taką samą sytuację, gdy korzystałem tylko z nazwy namesspace.class, aby uzyskać typ klasy w innym zestawie i to nie działałoby. Działa tylko wtedy, gdy dołączam informacje o złożeniu do mojego ciągu typu, jak pokazano powyżej.


3

Upewnij się, że przecinek znajduje się bezpośrednio za pełną nazwą

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

Ponieważ to nie zadziała

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

Przez kilka dni byłem w tym zdumiony


2

Dla mnie kluczem był „+”! To jest moja klasa (jest to zagnieżdżona):

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

i ta linia kodu działała:

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

1

Powyższe rozwiązanie wydaje mi się najlepsze, ale dla mnie nie zadziałało, więc zrobiłem to w następujący sposób:

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

Type myType = Type.GetType(typeAssemblyQualifiedName);

Warunkiem jest znajomość ścieżki zgromadzenia. W moim przypadku wiem o tym, ponieważ jest to zestaw zbudowany z innego projektu wewnętrznego i jest zawarty w folderze bin naszego projektu.

W przypadku, gdy ma to znaczenie, używam Visual Studio 2013, mój docelowy .NET to 4.0. To projekt ASP.NET, więc otrzymuję ścieżkę bezwzględną HttpContext. Jednak ścieżka bezwzględna nie jest wymagana, jak się wydaje z MSDN na AssemblyQualifiedNames


0

Oszukiwałem. Ponieważ wszystkie typy, które chcę utworzyć (według nazwy), znajdują się w kontrolowanej przeze mnie bibliotece DLL, po prostu umieściłem metodę statyczną w bibliotece DLL w zestawie, która przyjmuje prostą nazwę i wywołuje typ.GetType z tego kontekstu i zwraca wynik .

Pierwotny cel polegał na tym, że typ można określić według nazwy w danych konfiguracyjnych. Od tego czasu zmieniłem kod, aby użytkownik określił format do przetworzenia. Klasy procedur obsługi formatu implementują interfejs, który określa, czy typ może przeanalizować określony format. Następnie używam refleksji, aby znaleźć typy implementujące interfejs i znaleźć taki, który obsługuje format. Więc teraz konfiguracja określa nazwę formatu, a nie określonego typu. Kod odbicia może patrzeć na sąsiadujące biblioteki DLL i ładować je, więc mam architekturę wtyczki biednego człowieka.


Cześć, przez pomyłkę głosowałem, edytuj swoją odpowiedź, aby ją cofnąć.
coloboxp
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.