2009-09-08 13 views
12

Próbuję uzyskać obiekt typu z pełną nazwą typu robię folowing:Tworzenie typ C# od pełnej nazwy

Assembly asm = Assembly.GetEntryAssembly(); 
string toNativeTypeName="any type full name"; 
Type t = asm.GetType(toNativeTypeName); 

otrzymuję null, dlaczego?

zespół jest mój plik wykonywalny (.NET wykonywalny) i nazwa typu jest: System.Xml.XmlNode

+0

Pokaż nam, co masz na myśli przez pełne imię i nazwisko? – AnthonyWJones

+0

Zgromadzenie to mój plik wykonywalny (plik wykonywalny .net), a nazwa typu brzmi: System.Xml.XmlNode –

+0

System.Xml.XmlNode nie będzie istnieć w zespole, więc powinieneś użyć Type.GetType inestead of Assembly.GetType. –

Odpowiedz

27

Cóż, jeśli to naprawdę jest pełna nazwa typu (tzn w tym nazw) i to jest w tym zespole, to powinno działać. Czy możesz podać przykład, w którym nie jest? Ponieważ używasz Assembly.GetType zamiast Type.GetType, nie należy zawierać nazwy zespołu w nazwie typu.

Należy pamiętać, że nazwa typu ogólnego nie jest tym, czego można się spodziewać. Na przykład, można użyć:

assembly.GetType("System.Collections.Generic.List`1"); 

aby uzyskać ogólny typ listy, a następnie użyć Type.MakeGenericType dostarczenie argumentów typu.

Oczywiście ma to znaczenie tylko wtedy, gdy typ jest ogólny. Jeśli to nie jest problem, sprawdziłbym dokładnie, czy typ rzeczywiście znajduje się w twoim zespole wejścia.

EDIT: Aha, i mieć świadomość, że zagnieżdżone typy będzie „Kontener + zagnieżdżony” zamiast „Container.Nested” jeśli to istotne ...

+0

Zgromadzenie to mój plik wykonywalny (plik wykonywalny .net), a nazwa typu to: System.Xml.XmlNode –

+4

Wtedy jest problem: System.Xml.XmlNode nie jest typem w twoim zespole, czyż nie? Musisz użyć odpowiedniego zespołu lub wywołać Type.GetType z pełną informacją o złożeniu. –

+0

+1 Wiele dobrych informacji tutaj. –

4

Twoja nazwa typu jest najprawdopodobniej źle. Jeśli utworzysz odwołanie do typu w kodzie, a następnie zaznaczysz jego właściwość Type.FullName, zobaczysz, jak powinna wyglądać nazwa typu.

Możesz także wypróbować metodę Type.GetType i zobaczyć, co zwraca. Może twój typ w ogóle nie jest w tym zespole?

Edytuj: Okazuje się, że myliłem się co do używania właściwości Type.FullName. Jeśli użyjesz właściwości Type.AssemblyQualifiedName, uzyskasz pełną nazwę, która może być używana przez Type.GetType.

Dla System.Xml.XmlNode można uzyskać następującą nazwę: System.Xml.XmlElement, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

6

dlaczego definiowania montaż używać się wpisać !, również trzeba umieścić namespace

string toNativeTypeName = "System.Int32"; 
Type t = Type.GetType(toNativeTypeName); 
MessageBox.Show(t.FullName); 
+3

Jeśli wiesz, że typ * jest * w zespole wejścia, a następnie przy użyciu Assembly.GetType z nazwą obejmującą przestrzeń nazw, ale * nie * nazwa zespołu może być o wiele łatwiejsze niż dołączenie pełnej nazwy zespołu, w tym wersji ... –

+0

To mi pomogło. Próbowałem pobrać wiadomości szeregowe z kolejki. Testowałem z System.String i nie znajdowałem go podczas przechodzenia przez wszystkie złożenia z bieżącej domeny. Po zmianie na Type.GetType po prostu zadziałało. Dzięki za wskazówkę. – fizch

3

natknąłem tego wątku i zauważyłem, że pierwotne pytanie nie zostało odebrane. Mogę się mylić, ale czytając pytanie, myślę, że intencją autorów było po prostu uzyskanie typu ze zgromadzenia, do którego się odwołujesz, lub części twojej aplikacji.

Oto, co zrobiłem, aby rozwiązać ten problem.

public static Type GetTypeFromFullName(string fullClassName) 
{ 
    AssemblyPartCollection parts = Deployment.Current.Parts; 

    foreach (var part in parts) 
    { 
     Uri resUri = new Uri(part.Source, UriKind.Relative); 
     Stream resStream = Application.GetResourceStream(resUri).Stream; 
     Assembly resAssembly = part.Load(resStream); 
     Type tryType = resAssembly.GetType(fullClassName, false); 
     if (tryType != null) 
      return tryType; 
    } 

    return null; 
} 
8

Poniżej moja propozycja, tylko zapętlenie nazw biznesowe dla prędkości

private static Type GetBusinessEntityType(string typeName) 
{ 
    Debug.Assert(typeName != null); 

    List<System.Reflection.Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies() 
     .Where(a => a.FullName.StartsWith("AF.BusinessEntities")).ToList(); 

    foreach (var assembly in assemblies) 
    { 
     Type t = assembly.GetType(typeName, false); 
     if (t != null) 
      return t; 
    } 
    throw new ArgumentException(
     "Type " + typeName + " doesn't exist in the current app domain"); 
} 

Oto kolejny sposób, aby to zrobić:

Type t = System.Web.Compilation.BuildManager.GetType("the.type", true, false); 

Użyj reflektor, aby zobaczyć, jak to zrobić, przynajmniej na zabawa :)

+1

Zrobiłem to za pomocą 'System.Web.Compilation.BuildManager', z którego nie mogłem pracować dla Enum:' NLibrary + Modules' – Niels

Powiązane problemy