本人来源于我在学习JAVA的反射过程中,想了解一下C#的反射过程,所以写了一下知识总结,希望能为后来者的一些帮助
反射提供了描述程序集、模块和类型的对象( Type 类型)。 可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了特性,可以利用反射来访问它们。
我自建立供反射测试的类库如下:分别是Class Car and Class Deep
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ClassLibrary1 { class deep:Car { private string name; public void run() { System.Console.WriteLine("deep run method"); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ClassLibrary1 { public class Car { private string name; public int i; public string Name { get { return name; } set { name = value; } } public void run() { System.Console.WriteLine("car run method"); } public string myReturnMethod(string abc) { System.Console.WriteLine("car run myReturnMethod"); return abc; } //protected void run() //{ // System.Console.WriteLine("car run method"); //} } }
- 使用 Assembly 类可以加载程序集、浏览程序集的元数据和构成部分、发现程序集中包含的类型以及创建这些类型的实例。
Assembly 类的许多成员都提供有关程序集的信息
- GetName 方法返回一个 AssemblyName 对象,该对象提供对程序集显示名称部分的访问。
- GetCustomAttributes 方法列出应用于程序集的属性。
- GetFiles 方法提供对程序集清单中文件的访问。
- GetManifestResourceNames 方法提供程序集清单中资源的名称。
1.1 若要获取 Assembly 对象(表示当前加载到应用程序域(例如,简单项目的默认应用程序域)中的程序集)的数组,可以使用 AppDomain ..::. GetAssemblies 方法。
AppDomain currentDomain = AppDomain.CurrentDomain; //获取当前 Thread 的当前应用程序域。 Assembly[] assems = currentDomain.GetAssemblies(); //获取已加载到此应用程序域的执行上下文中的程序集。 Console.WriteLine("List of assemblies loaded in current appdomain:"); foreach (Assembly assem in assems) { Console.WriteLine(assem.ToString()); }
1.2加载程序集的推荐方式是使用 Load 方法,该方法标识要由其显示名称加载的程序集
//调用非本程序的DLL ,注意这里的ClassLibrary1是我写的类库文件
Assembly assem = Assembly.Load("ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); //或者使用下面语句代替前一语句 //Assembly assem = Assembly.LoadFrom("ClassLibrary1.dll"); Console.Write(assem.FullName); AssemblyName assemName = assem.GetName(); Console.WriteLine("\nName: {0}", assemName.Name); Console.WriteLine("Version: {0}.{1}", assemName.Version.Major, assemName.Version.Minor); ///查看该类库下的所有类名 int i,j; Type[] types = assem.GetTypes(); //获取类名 for (i = 0; i < types.GetLength(0); ++i) { Console.WriteLine(types[i].Name); }
- 2. 使用 FieldInfo 发现以下信息:字段的名称、访问修饰符(如 public 或 private)和实现详细信息(如 static)等;并获取或设置字段值。
这里简单获取该类库中的第一个类作例子
Type mytype = types[0]; FieldInfo[] myFieldInfo; myFieldInfo = mytype.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); for (i = 0; i < myFieldInfo.Length; i++) { Console.WriteLine("\nName : {0}", myFieldInfo[i].Name); Console.WriteLine("Declaring Type : {0}", myFieldInfo[i].DeclaringType); Console.WriteLine("IsPublic : {0}", myFieldInfo[i].IsPublic); Console.WriteLine("MemberType : {0}", myFieldInfo[i].MemberType); Console.WriteLine("FieldType : {0}", myFieldInfo[i].FieldType); Console.WriteLine("IsFamily : {0}", myFieldInfo[i].IsFamily); }