1 反射的基本原理是什么?
反射是一种动态分析程序集、模块、类型及字段等目标对象的机制,实现依托于元数据。
元数据,就是描述数据的数据。在CLR中,元数据就是对一个模块定义或引用的所有东西的描述系统。
2 .NET中提供了哪些类型实现反射?
在.NET中,这些类型大多数都定义在System.Reflection命名空间之下,例如Assembly、Module等。
利用这些类型,我们就可以方便地动态加载程序集、模块、类型、方法和字段等元素。
[Serializable] class SimpleClass { private String _MyString; public SimpleClass(String mystring) { _MyString = mystring; } public override string ToString() { return _MyString; } static void Main(string[] args) { Console.WriteLine("简单程序集"); Console.Read(); } } public class AnalyseHelper { /// <summary> /// 分析程序集 /// </summary> public static void AnalyzeAssembly(Assembly assembly) { Console.WriteLine("程序集名字:" + assembly.FullName); Console.WriteLine("程序集位置:" + assembly.Location); Console.WriteLine("程序集是否在GAC中:" + assembly.GlobalAssemblyCache.ToString()); Console.WriteLine("包含程序集的模块名" + assembly.ManifestModule.Name); Console.WriteLine("运行程序集需要的CLR版本:" + assembly.ImageRuntimeVersion); Console.WriteLine("现在开始分析程序集中的模块"); Module[] modules = assembly.GetModules(); foreach (Module module in modules) { AnalyzeModule(module); } } /// <summary> /// 分析模块 /// </summary> public static void AnalyzeModule(Module module) { Console.WriteLine("模块名:" + module.Name); Console.WriteLine("模块的UUID:" + module.ModuleVersionId); Console.WriteLine("开始分析模块下的类型"); Type[] types = module.GetTypes(); foreach (Type type in types) { AnalyzeType(type); } } /// <summary> /// 分析类型 /// </summary> public static void AnalyzeType(Type type) { Console.WriteLine("类型名字:" + type.Name); Console.WriteLine("类型的类别是:" + type.Attributes); if (type.BaseType != null) Console.WriteLine("类型的基类是:" + type.BaseType.Name); Console.WriteLine("类型的GUID是:" + type.GUID); //设置感兴趣的类型成员 BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); //分析成员 FieldInfo[] fields = type.GetFields(flags); if (fields.Length > 0) { //Console.WriteLine("开始分析类型的成员"); foreach (FieldInfo field in fields) { // 分析成员 } } //分析包含的方法 MethodInfo[] methods = type.GetMethods(flags); if (methods.Length > 0) { //Console.WriteLine("开始分析类型的方法"); foreach (MethodInfo method in methods) { // 分析方法 } } //分析属性 PropertyInfo[] properties = type.GetProperties(flags); if (properties.Length > 0) { //Console.WriteLine("开始分析类型的属性"); foreach (PropertyInfo property in properties) { // 分析属性 } } }
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] class Program { static void Main(string[] args) { Assembly assembly = Assembly.LoadFrom(@"..\..\..\SimpleAssembly\bin\Debug\SimpleAssembly.exe"); AnalyseHelper.AnalyzeAssembly(assembly); // 创建一个程序集中的类型的对象 Console.WriteLine("利用反射创建对象"); string[] paras = { "测试一下反射效果" }; object obj = assembly.CreateInstance(assembly.GetModules()[0].GetTypes()[0].ToString(), true, BindingFlags.CreateInstance, null, paras, null, null); Console.WriteLine(obj); Console.ReadKey(); } }
上面的代码按照 程序集->模块->类型 三个层次的顺序来动态分析一个程序集,当然还可以继续递归类型内部的成员,最后通过CreateInstance方法来动态创建了一个类型,这些都是反射经常被用来完成的功能,执行结果如下图所示:
时间: 2024-10-06 05:32:09