tutorial net español c# .net reflection namespaces

c# - net - Obteniendo todos los tipos en un espacio de nombres a través de la reflexión.



reflection c# tutorial (11)

¿Cómo se obtienen todas las clases en un espacio de nombres a través de la reflexión en C #?


Al igual que @aku responde, pero usando métodos de extensión:

string @namespace = "..."; var types = Assembly.GetExecutingAssembly().GetTypes() .Where(t => t.IsClass && t.Namespace == @namespace) .ToList(); types.ForEach(t => Console.WriteLine(t.Name));


Aquí hay una solución para los errores LoaderException que es probable que encuentre si uno de los tipos sub-clasifica un tipo en otro ensamblaje:

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

Eso debería ayudar con la carga de tipos definidos en otros ensamblajes.

¡Espero que ayude!


Bastante sencillo

Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes(); foreach (var item in types) { }


Como dice FlySwat, puede tener el mismo espacio de nombres que abarca varios ensamblajes (por ejemplo, System.Collections.Generic ). Tendrá que cargar todos esos ensamblajes si aún no están cargados. Así que para una respuesta completa:

AppDomain.CurrentDomain.GetAssemblies() .SelectMany(t => t.GetTypes()) .Where(t => t.IsClass && t.Namespace == @namespace)

Esto debería funcionar a menos que quieras clases de otros dominios. Para obtener una lista de todos los dominios, siga este enlace.


Los espacios de nombres son en realidad bastante pasivos en el diseño del tiempo de ejecución y sirven principalmente como herramientas de organización. El nombre completo de un tipo en .NET consiste en el espacio de nombres y Class / Enum / Etc. conjunto. Si solo desea pasar por un ensamblaje específico, simplemente debe recorrer los tipos devueltos por el ensamblaje. GetExportedTypes() comprueba el valor del tipo. Namespace . Si intentara pasar por todos los ensamblados cargados en el dominio de aplicación actual, esto implicaría el uso del dominio de aplicación. GetAssemblies()


No podrá obtener todos los tipos en un espacio de nombres, ya que un espacio de nombres puede unir múltiples ensamblajes, pero puede obtener todas las clases en un ensamblaje y verificar si pertenecen a ese espacio de nombres.

Assembly.GetTypes() funciona en el ensamblado local, o puede cargar un ensamblaje primero y luego llamar a GetTypes() en él.


Obtenga todas las clases por parte del nombre del espacio de nombres en una sola fila:

var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();


Para una Asamblea específica, con un filtro de nombre de clase:

var asm = Assembly.Load("Some.Assembly.Name"); var nameSpace = "Some.Namespace.Name"; var classes = asm.GetTypes().Where(p => p.Namespace == nameSpace && p.Name.Contains("ClassNameFilter") ).ToList();

Nota: El proyecto debe hacer referencia al montaje.


El siguiente código imprime los nombres de las clases en el namespace especificado definido en el ensamblaje actual.
Como señalaron otros tipos, un espacio de nombres se puede dispersar entre diferentes módulos, por lo que primero debe obtener una lista de ensamblajes.

string nspace = "..."; var q = from t in Assembly.GetExecutingAssembly().GetTypes() where t.IsClass && t.Namespace == nspace select t; q.ToList().ForEach(t => Console.WriteLine(t.Name));


//a simple combined code snippet using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace MustHaveAttributes { class Program { static void Main ( string[] args ) { Console.WriteLine ( " START " ); // what is in the assembly Assembly a = Assembly.Load ( "MustHaveAttributes" ); Type[] types = a.GetTypes (); foreach (Type t in types) { Console.WriteLine ( "Type is {0}", t ); } Console.WriteLine ( "{0} types found", types.Length ); #region Linq //#region Action //string @namespace = "MustHaveAttributes"; //var q = from t in Assembly.GetExecutingAssembly ().GetTypes () // where t.IsClass && t.Namespace == @namespace // select t; //q.ToList ().ForEach ( t => Console.WriteLine ( t.Name ) ); //#endregion Action #endregion Console.ReadLine (); Console.WriteLine ( " HIT A KEY TO EXIT " ); Console.WriteLine ( " END " ); } } //eof Program class ClassOne { } //eof class class ClassTwo { } //eof class [System.AttributeUsage ( System.AttributeTargets.Class | System.AttributeTargets.Struct, AllowMultiple = true )] public class AttributeClass : System.Attribute { public string MustHaveDescription { get; set; } public string MusHaveVersion { get; set; } public AttributeClass ( string mustHaveDescription, string mustHaveVersion ) { MustHaveDescription = mustHaveDescription; MusHaveVersion = mustHaveVersion; } } //eof class } //eof namespace


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

NB: El código anterior ilustra lo que está pasando. Si lo implementas, puedes usar una versión simplificada:

using System.Linq; using System.Reflection; using System.Collections.Generic; //... static IEnumerable<string> GetClasses(string nameSpace) { Assembly asm = Assembly.GetExecutingAssembly(); return asm.GetTypes() .Where(type => type.Namespace == nameSpace) .Select(type => type.Name); }