2009-09-08 24 views
12

Sto cercando di ottenere un oggetto Type dal tipo di nome e cognome sto facendo il folowing:Creazione di C# Tipo dal nome completo

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

ottengo nulla, perché?

l'assemblea è la mia eseguibile (.net eseguibile) e il nome del tipo è: System.Xml.XmlNode

+0

Mostraci cosa intendi per nome completo? – AnthonyWJones

+0

l'assembly è il mio eseguibile (.net eseguibile) e il nome del tipo è: System.Xml.XmlNode –

+0

System.Xml.XmlNode non esiste nell'assembly, pertanto è necessario utilizzare Type.GetType inestead di Assembly.GetType. –

risposta

27

Beh, se questo è in realtà il nome completo del tipo (ad esempio compresa namespace) ed è in quell'assemblea, allora dovrebbe funzionare. Puoi dare un esempio dove non lo fa? Poiché stai utilizzando Assembly.GetType anziché Type.GetType, non devi includere il nome dell'assembly nel nome del tipo.

Si noti che il nome per un tipo generico non è quello che ci si potrebbe aspettare che sia. Per esempio, utilizza:

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

per ottenere il tipo di elenco generico, quindi utilizzare Type.MakeGenericType per fornire argomenti di tipo.

Naturalmente, ciò è rilevante solo quando il tipo è generico. Se questo non è il problema, controllerò di nuovo che il tipo sia realmente nell'assembly di ingresso.

EDIT: Oh, ed essere consapevoli che i tipi annidati saranno "Container + nidificati" piuttosto che "Container.Nested" se questo è rilevante ...

+0

l'assembly è il mio eseguibile (.net eseguibile) e il nome del tipo è: System.Xml.XmlNode –

+4

Quindi questo è il problema: System.Xml.XmlNode non è un tipo all'interno dell'assembly, vero? È necessario utilizzare l'assembly corretto oppure chiamare Type.GetType con le informazioni complete sull'assembly. –

+0

+1 Un sacco di buone informazioni qui. –

4

tuo nome tipo è più probabilmente sbagliato. Se crei un riferimento al codice digitato e poi controlli la sua proprietà Type.FullName vedrai come dovrebbe apparire il nome del tipo.

Inoltre, è possibile provare il metodo Type.GetType e vedere cosa restituisce. Forse il tuo tipo non è affatto in quell'assemblea?

Modifica: Si è verificato un errore nell'utilizzo della proprietà Type.FullName. Se si utilizza la proprietà Type.AssemblyQualifiedName, verrà visualizzato il nome completo che può essere utilizzato da Type.GetType.

Per System.Xml.XmlNode si ottiene il seguente nome: System.Xml.XmlElement, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

6

motivo per cui si sta definendo il montaggio da usare ottenere il tipo !, anche è necessario mettere namespace

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

Se si sa che il tipo * è * nell'assembly della voce, quindi usando Assembly.GetType con il nome incluso lo spazio dei nomi ma * non * il nome dell'assembly può essere molto più semplice che includere il nome completo dell'assembly inclusa la versione ... –

+0

Questo mi ha aiutato. Stavo cercando di estrarre i messaggi serializzati da una coda. Stavo testando con System.String e non trovandolo mentre eseguivo il loop su tutti gli assembly dal dominio corrente. Quando cambio di usare Type.GetType, ha funzionato. Grazie per il consiglio. – fizch

3

mi sono imbattuto in questa discussione e ho notato che la domanda originale non ha ancora avuto risposta. Potrei sbagliarmi, ma leggendo la domanda penso che gli autori intendessero essere in grado di ottenere semplicemente un Type da un Assembly a cui fa riferimento o parte della tua applicazione.

Ecco cosa ho fatto per risolvere questo problema.

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

Vedere il mio suggerimento di seguito, solo loop spazio dei nomi di business per la velocità

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

Ecco un altro modo per farlo:

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

Usa riflettore per vedere come è fatto, almeno per divertimento :)

+1

Il 'System.Web.Compilation.BuildManager' ha fatto per me, l'altro non l'ho fatto funzionare per un Enum:' NLibrary + Modules' – Niels

Problemi correlati