2008-10-07 4 views
31

Je souhaite obtenir un System.Type donné uniquement le nom du type dans un string.Obtention d'un System.Type à partir du nom partiel du type

Par exemple, si j'ai un objet:

MyClass abc = new MyClass(); 

je peux alors dire:

System.Type type = abc.GetType(); 

Mais si tout ce que j'ai est:

string className = "MyClass"; 
+0

duplication possible de [Évitez de donner le nom de l'espace de nom dans Type.GetType()] (http: // stackoverflow .com/questions/9273629/eviter-donner-namespace-nom-dans-type-gettype) – Fr33dan

+0

@ Fr33dan, Boucle circulaire? Le mentionné possible [original] (http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type-gettype) mentionne [cette question] (http://stackoverflow.com/questions/179102/get-a-system-type-from-types-partial-name) comme original possible (voir [commentaire] (http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type- gettype # comment39575691_9273629))? :) – publicgk

+0

@publicgk J'étais en train d'essayer de le marquer pour une fusion avec cette question, car ils sont les mêmes mais cette question et les deux ont de bonnes réponses. Voir [cette question meta] (http://meta.stackoverflow.com/q/269080/1111886). Je l'ai fait mal apparemment et abandonné, puis quelqu'un est venu plus tard et a décidé que c'était le doublon puisque l'autre était une question plus ancienne. – Fr33dan

Répondre

33
Type type = Type.GetType("foo.bar.MyClass, foo.bar"); 

MSDN. Assurez-vous que le nom est Assembly Qualified.

+1

Une note importante: Elle nécessite le nom de type complet. – leppie

2
Type type = Type.GetType("MyClass"); 

Assurez-vous d'inclure l'espace de noms. Il existe des surcharges de la méthode qui contrôlent la sensibilité à la casse et si une exception est levée si le nom du type n'est pas trouvé.

+1

Incorrect, vous devez également spécifier l'assembly. –

+2

Cela ne fonctionnera pas :) – leppie

+1

De la documentation, "Si le type est dans l'assembly en cours d'exécution ou dans Mscorlib.dll, il suffit de fournir le nom de type qualifié par son espace de noms." – jalbert

2

Pour créer une instance de votre classe après que vous obtenez le type, et appeler une méthode -

Type type = Type.GetType("foo.bar.MyClass, foo.bar"); 
object instanceObject = System.Reflection.Activator.CreateInstance(type); 
type.InvokeMember(method, BindingFlags.InvokeMethod, null, instanceObject, new object[0]); 
0

Type.GetType(...) peut échouer parfois si l'opérateur typeof ne peut pas être utilisé. A la place, vous pouvez réfléchir sur les assemblages du domaine actuel pour le faire.

vérifier ma réponse sur this thread

1

Une autre façon d'obtenir le type de courant ou d'une autre assebly.

(Suppose que l'espace de noms de classe contient son assemblée):


public static Type GetType(string fullName) 
{ 
    if (string.IsNullOrEmpty(fullName)) 
     return null; 
    Type type = Type.GetType(fullName); 
    if (type == null) 
    { 
     string targetAssembly = fullName; 
     while (type == null && targetAssembly.Length > 0) 
     { 
      try 
      { 
       int dotInd = targetAssembly.LastIndexOf('.'); 
       targetAssembly = dotInd >= 0 ? targetAssembly.Substring(0, dotInd) : ""; 
       if (targetAssembly.Length > 0) 
        type = Type.GetType(fullName + ", " + targetAssembly); 
      } 
      catch { } 
     } 
    } 
    return type; 
} 
0

Voici une méthode simple pour la création et l'initialisation d'un nouvel objet de son nom et les paramètres:

// Creates and initializes a new object from its name and parameters 
    public Object CreateObjectByName(string name, params Object[] args) 
    { 
     string s = "<prefix>" + name; // case sensitive; Type.FullName 
     Type type = Type.GetType(s); 
     Object o = System.Activator.CreateInstance(type, args); 
     return o; 
    } 

Un exemple de la façon dont on pourrait utiliser ceci est de lire un fichier contenant des noms de classe [ou des noms de classe partiels] et des paramètres, puis d'ajouter les objets renvoyés à une liste d'objets d'un type de base qui est commo. n aux objets créés.

Pour voir ce que votre nom de classe [ou] devrait ressembler, utiliser temporairement quelque chose comme ça [si votre classe est nommée NewClass]:

string z = (new NewClass(args)).GetType().FullName; 
33

Cela dépend de l'ensemble de la classe est.Si elle est en mscorlib ou en appelant l'ensemble tout ce que vous avez besoin est

Type type = Type.GetType("namespace.class"); 

Mais si elle est référencée à partir d'une autre assemblée, vous devez faire:

Assembly assembly = typeof(SomeKnownTypeInAssembly).Assembly; 
Type type = assembly.GetType("namespace.class"); 

//or 

Type type = Type.GetType("namespace.class, assembly"); 

Si vous avez seulement le nom de classe "MyClass", vous devez obtenir le nom de l'espace de nom (ou le nom de l'espace de nom et le nom de l'assembly si c'est un assembly référencé) et le concaténer avec le nom de la classe. Quelque chose comme:

//if class is in same assembly 
var namespace = typeof(SomeKnownTypeInNamespace).Namespace; 
Type type = Type.GetType(namespace + "." + "MyClass"); 


//or for cases of referenced classes 
var assembly = typeof(SomeKnownTypeInAssembly).Assembly; 
var namespace = typeof(SomeKnownTypeInNamespace).Namespace; 
Type type = assembly.GetType(namespace + "." + "MyClass"); 
//or 
Type type = Type.GetType(namespace + "." + "MyClass" + ", " + assembly.GetName().Name); 

Si vous avez absolument rien (pas preawareness de même le nom d'assembly ou le nom d'espace de noms) mais juste le nom de la classe, alors vous pouvez interroger l'ensemble des ensembles pour sélectionner une chaîne correspondante. Mais cela devrait être beaucoup plus lent:

Type type = AppDomain.CurrentDomain.GetAssemblies() 
            .SelectMany(x => x.GetTypes()) 
            .FirstOrDefault(x => x.Name == "MyClass"); 

Notez que cela retourne la première classe correspondant, donc pas besoin d'être très précis si vous auriez plusieurs classes avec le même nom dans les ensembles/namespaces. Dans tous les cas, la mise en cache des valeurs est logique ici. manière un peu plus rapide est de supposer qu'il ya un espace de noms par défaut:

Type type = AppDomain.CurrentDomain.GetAssemblies() 
            .Select(a => new { a, a.GetTypes().First().Namespace }) 
            .Select(x => x.a.GetType(x.Namespace + "." + "MyClass")) 
            .FirstOrDefault(x => x != null); 

Mais c'est encore une hypothèse que le type aura le même espace que d'une autre classe au hasard dans l'assemblée; trop fragile, pas très bon.


Si vous voulez des cours d'autres domaines que vous pouvez obtenir une liste de tous les domaines d'application suivants, this link. Vous pouvez faire la même interrogation que montré ci-dessus pour chaque domaine. Si votre assembly où le type réside n'est pas encore chargé, vous devez le charger manuellement en utilisant Assembly.Load, Assembly.LoadFrom etc.

Questions connexes