通过反射获取名称空间中的所有类型
时间:2020-03-05 18:57:50 来源:igfitidea点击:
如何通过C#中的反射获取命名空间中的所有类?
解决方案
回答
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; }
注意:上面的代码说明了正在发生的事情。如果要实现它,可以使用简化版本:
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); }
回答
我们将无法在一个名称空间中获取所有类型,因为一个名称空间可以桥接多个程序集,但是我们可以在一个程序集中获取所有类,并检查它们是否属于该名称空间。
Assembly.GetTypes()
在本地程序集上有效,或者我们可以先加载程序集,然后在其上调用GetTypes()
。
回答
以下代码在当前程序集中定义的指定"名称空间"中打印类的名称。
正如其他人指出的那样,名称空间可以分散在不同的模块之间,因此我们需要首先获取程序集列表。
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));
回答
命名空间实际上在运行时的设计中是被动的,并且主要用作组织工具。 .NET中类型的全名由命名空间和Class / Enum / Etc组成。结合。如果只希望通过特定的程序集,则只需遍历Assembly.GetExportedTypes()返回的类型,并检查type.Namespace的值。如果尝试遍历当前AppDomain中加载的所有程序集,则将涉及使用AppDomain.CurrentDomain.GetAssemblies()
回答
这是一个针对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); }
这应该有助于加载其他程序集中定义的类型。
希望对我们有所帮助!
回答
//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