Comment obtenir toutes les classes d'un espace de noms par réflexion en C# ?
Réponses
Trop de publicités?Le code suivant imprime les noms des classes dans les ns spécifiées définies dans l'assemblage actuel.
Comme l'ont souligné d'autres personnes, les espaces de noms peuvent être dispersés entre différents modules, vous devez donc d'abord obtenir une liste des assemblages.
string @namespace = "...";
var q = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsClass && t.Namespace == @namespace
select t;
q.ToList().ForEach(t => Console.WriteLine(t.Name));
Comme FlySwat l'a dit, vous pouvez avoir le même espace de nom dans plusieurs assemblages (par ex. System.Collections.Generic
). Vous devrez charger tous ces assemblages s'ils ne sont pas déjà chargés. Donc pour une réponse complète :
AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(t => t.GetTypes())
.Where(t => t.IsClass && t.Namespace == @namespace)
Cela devrait fonctionner, sauf si vous voulez des classes d'autres domaines. Pour obtenir une liste de tous les domaines, suivez les instructions suivantes ce lien.
using System.Reflection;
using System.Collections.Generic;
//...
static List<string> GetClasses(string nameSpace)
{
Assembly asm = Assembly.GetExecutingAssembly();
List<string> namespacelist = new List<string>();
List<string> classlist = new List<string>();
foreach (Type type in asm.GetTypes())
{
if (type.Namespace == nameSpace)
namespacelist.Add(type.Name);
}
foreach (string classname in namespacelist)
classlist.Add(classname);
return classlist;
}
Voici un correctif pour les erreurs LoaderException que vous êtes susceptible de trouver si l'un des types sous-classe un type dans une autre assemblée :
// Setup event handler to resolve assemblies
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
Assembly a = System.Reflection.Assembly.ReflectionOnlyLoadFrom(filename);
a.GetTypes();
// process types here
// method later in the class:
static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}
Cela devrait aider à charger les types définis dans d'autres assemblages.
J'espère que cela vous aidera !
Vous ne pourrez pas obtenir tous les types d'un espace de noms, car un espace de noms peut relier plusieurs assemblages, mais vous pouvez obtenir toutes les classes d'un assemblage et vérifier si elles appartiennent à cet espace de noms.
Assembly.GetTypes()
fonctionne sur l'assemblage local, ou vous pouvez d'abord charger un assemblage puis appeler GetTypes()
sur elle.
- Réponses précédentes
- Plus de réponses