304 votes

Obtenir tous les types dans un espace de noms via la réflexion

Comment obtenir toutes les classes d'un espace de noms par réflexion en C# ?

343voto

aku Points 54867

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

104voto

nawfal Points 13500

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.

33voto

Ryan Farley Points 7916
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;
}

14voto

Travis Points 6062

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 !

10voto

FlySwat Points 61945

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X