Getting all types in a namespace via reflection
如何通过C中的反射获得名称空间中的所有类?
下面的代码打印当前程序集中定义的指定
1 2 3 4 5 6 | 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)); |
正如flyswat所说,您可以在多个程序集中拥有相同的名称空间(例如
1 2 3 | AppDomain.CurrentDomain.GetAssemblies() .SelectMany(t => t.GetTypes()) .Where(t => t.IsClass && t.Namespace == @namespace) |
除非您想要其他域的类,否则这应该可以工作。要获取所有域的列表,请使用此链接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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; } |
注意:上面的代码说明了正在发生的事情。如果要实现它,可以使用简化版本:
1 2 3 4 5 6 7 8 9 10 11 12 | 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); } |
对于特定程序集、命名空间和类名:
1 2 3 4 5 6 7 8 9 | var assemblyName ="Some.Assembly.Name" var nameSpace ="Some.Namespace.Name"; var className ="ClassNameFilter"; var asm = Assembly.Load(assemblyName); var classes = asm.GetTypes().Where(p => p.Namespace == nameSpace && p.Name.Contains(className) ).ToList(); |
注意:项目必须引用程序集
下面是对loaderException错误的修复,您可能会发现,如果其中一个类型子类在另一个程序集中对某个类型进行了赋值,则会出现以下错误:
1 2 3 4 5 6 7 8 9 10 11 12 | // 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); } |
这有助于加载在其他程序集中定义的类型。
希望有帮助!
您将无法获取命名空间中的所有类型,因为命名空间可以桥接多个程序集,但可以获取程序集中的所有类,并检查它们是否属于该命名空间。
仅在一行中按部分命名空间名称获取所有类:
1 | var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList(); |
就像@aku answer,但是使用扩展方法:
1 2 3 4 5 6 7 | string @namespace ="..."; var types = Assembly.GetExecutingAssembly().GetTypes() .Where(t => t.IsClass && t.Namespace == @namespace) .ToList(); types.ForEach(t => Console.WriteLine(t.Name)); |
名称空间实际上在运行时的设计中相当被动,主要用作组织工具。.NET中类型的全名由命名空间和class/enum/etc组合而成。如果只想遍历特定的程序集,只需遍历assembly.getexportedtypes()返回的类型,检查type.namespace的值。如果尝试遍历当前AppDomain中加载的所有程序集,则将涉及使用AppDomain.CurrentDomain.GetAssemblies()。
很简单
1 2 3 4 | Type[] types = Assembly.Load(new AssemblyName("mynamespace.folder")).GetTypes(); foreach (var item in types) { } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | //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 |