如何通过C#中的反射获取命名空间中的所有类?
下面的代码打印namespace
当前程序集中指定的类的名称.
正如其他人指出的那样,命名空间可以分散在不同的模块之间,因此您需要首先获得程序集列表.
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所说,您可以在多个程序集中使用相同的名称空间(例如System.Collections.Generic
).如果尚未加载,则必须加载所有这些程序集.所以有一个完整的答案:
AppDomain.CurrentDomain.GetAssemblies() .SelectMany(t => t.GetTypes()) .Where(t => t.IsClass && t.Namespace == @namespace)
除非您需要其他域的类,否则这应该有效.要获取所有域的列表,请单击此链接.
using System.Reflection; using System.Collections.Generic; //... static ListGetClasses(string nameSpace) { Assembly asm = Assembly.GetExecutingAssembly(); List namespacelist = new List (); List classlist = new List (); foreach (Type type in asm.GetTypes()) { if (type.Namespace == nameSpace) namespacelist.Add(type.Name); } foreach (string classname in namespacelist) classlist.Add(classname); return classlist; }
注意:上面的代码说明了发生了什么.如果您要实现它,可以使用简化版本:
using System.Linq; using System.Reflection; using System.Collections.Generic; //... static IEnumerableGetClasses(string nameSpace) { Assembly asm = Assembly.GetExecutingAssembly(); return asm.GetTypes() .Where(type => type.Namespace == nameSpace) .Select(type => type.Name); }
对于特定的Assembly,NameSpace和ClassName:
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错误的修复:
// 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); }
这应该有助于加载在其他程序集中定义的类型.
希望有所帮助!
您将无法获取命名空间中的所有类型,因为命名空间可以桥接多个程序集,但您可以获取程序集中的所有类并检查它们是否属于该命名空间.
Assembly.GetTypes()
适用于本地程序集,或者您可以先加载程序集然后调用GetTypes()
它.
就像@aku回答,但使用扩展方法:
string @namespace = "..."; var types = Assembly.GetExecutingAssembly().GetTypes() .Where(t => t.IsClass && t.Namespace == @namespace) .ToList(); types.ForEach(t => Console.WriteLine(t.Name));
通过名称空间名称的一部分获取所有类,只需一行:
var allClasses = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.IsClass && a.Namespace != null && a.Namespace.Contains(@"..your namespace...")).ToList();