步步为营-31-反射基础
说明 :简单练习反射的基础包括获取dll中的数据,方法等
程序集之间互相调用可以通过:a添加引用,b引入命名空间,来实现.但是只能调用public修辞的方法和属性.另外还可通过程序集调用
1 创建一个控制台应用程序
2 创建一个类库,用于生成dll,注意修改属性,使其生成的路径为控制台应用程序bin/debug目录(方便修改)
3 获取程序集数据
加载程序集,获取程序集数据
3.1 加载程序集--Assembly.LoadFile(path);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static Assembly LoadAssembly() { //01 注意是绝对路径 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll"); //02 加载程序集 return Assembly.LoadFile(path); }
3.2 获取数据
3.2.1 方法A获得程序集所有数据类型 ass.GetTypes()
3.2.2 方法B获得程序集所有--public数据类型 ass.GetExportedTypes()
3.2.3 方法C根据数据名称获得指定数据,可以是私有的 ass.GetType("Common.Teacher")
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#region 02-获取数据(abc三种常见的方法) /// <summary> /// 方法A获得程序集所有数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] A_GetTypes(Assembly ass) { Type[] types = ass.GetTypes(); return types; } /// <summary> /// 方法B获得程序集所有--public数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] B_GetExportedTypes(Assembly ass) { Type[] types = ass.GetExportedTypes(); return types; } /// <summary> /// 方法C根据数据名称获得指定数据,可以是私有的 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] C_GetType(Assembly ass) { Type atype = ass.GetType("Common.Teacher"); Type[] types = { atype }; return types; } #endregion
小结代码+运行效果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace 反射_基础 { class Program { static void Main(string[] args) { Assembly ass = LoadAssembly(); if (ass!=null) { Console.WriteLine("获得所有数据"); Type[] typesA = A_GetTypes(ass); ShowItem(typesA); Console.WriteLine(); Console.WriteLine("获得所有public数据"); Type[] typesB = B_GetExportedTypes(ass); ShowItem(typesB); Console.WriteLine(); Console.WriteLine("获得指定数据,可以是私有的"); Type[] typeC = C_GetType(ass); ShowItem(typeC); } Console.Read(); } #region 01加载程序集 public static Assembly LoadAssembly() { //01 注意是绝对路径 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll"); //02 加载程序集 return Assembly.LoadFile(path); } #endregion #region 02-获取数据(abc三种常见的方法) /// <summary> /// 方法A获得程序集所有数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] A_GetTypes(Assembly ass) { Type[] types = ass.GetTypes(); return types; } /// <summary> /// 方法B获得程序集所有--public数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] B_GetExportedTypes(Assembly ass) { Type[] types = ass.GetExportedTypes(); return types; } /// <summary> /// 方法C根据数据名称获得指定数据,可以是私有的 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] C_GetType(Assembly ass) { Type atype = ass.GetType("Common.Teacher"); Type[] types = { atype }; return types; } #endregion #region 03-显示数据 private static void ShowItem(Type[] types) { foreach (var item in types) { Console.WriteLine(item.Name); } } #endregion } }
4 创建对象
4.1 CreateInstance,注意是通过无参构造函数创建的.
4.2 Activator.CreateInstance创建对象
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#region 04创建对象(两种方法) /// <summary> /// 创建对象方法A,CreateInstance,注意是通过无参构造函数创建的. /// 方法B ,Activator.CreateInstance创建对象 /// </summary> /// <param name="ass"></param> /// <returns></returns> private static object A_CreateInstance(Assembly ass) { //object obj = ass.CreateInstance("Common.Student");//如果不含有 无参构造函数,会报错 object obj = ass.CreateInstance("Common.Teacher"); return obj; } /// <summary> /// 方法B ,Activator.CreateInstance创建对象 /// </summary> /// <param name="ass"></param> /// <returns></returns> private static object B_CreateInstance(Assembly ass) { //1获取创建对象的类型 Type type = ass.GetType("Common.Student"); object obj = Activator.CreateInstance(type,"张三",22); return obj; } #endregion
5 获取创建对象的属性,方法等
5.1.1GetMethods
5.1.2GetMethod
5.2.1GetProperties
5.2.2GetProperty
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#region 05获得创建对象的方法和属性 public static MethodInfo[] A_GetMethods(object obj) { MethodInfo[] mes = obj.GetType().GetMethods(); return mes; } public static MethodInfo[] B_GetMethod(object obj,string methodName) { MethodInfo me = obj.GetType().GetMethod(methodName); MethodInfo[] mes ={me}; return mes; } public static PropertyInfo[] A_GetProperties(object obj) { PropertyInfo [] prs = obj.GetType().GetProperties(); return prs; } public static PropertyInfo[] B_GetProperty(object obj, string proName) { PropertyInfo pr = obj.GetType().GetProperty(proName); PropertyInfo[] prs = { pr }; return prs; } #endregion
5.3 调用创建对象的SayHello方法
me[0].Invoke(objB, null);
5.4 获得Age属性的值
pro[0].SetValue(objB,55);
Console.WriteLine(pro[0].GetValue(objB));
代码小结:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace 反射_基础 { class Program { static void Main(string[] args) { Assembly ass = LoadAssembly(); if (ass!=null) { Console.WriteLine("获得所有数据"); Type[] typesA = A_GetTypes(ass); ShowItem(typesA); Console.WriteLine(); Console.WriteLine("获得所有public数据"); Type[] typesB = B_GetExportedTypes(ass); ShowItem(typesB); Console.WriteLine(); Console.WriteLine("获得指定数据,可以是私有的"); Type[] typeC = C_GetType(ass); ShowItem(typeC); //创建对象 Console.WriteLine(); Console.WriteLine("方法A创建对象(必须含有无参构造函数)"); object objA = A_CreateInstance(ass); Console.WriteLine(objA.GetType().Name); Console.WriteLine(); Console.WriteLine("方法B创建对象"); object objB = B_CreateInstance(ass); Console.WriteLine(objB.GetType().Name); Console.WriteLine(); //获得创建对象那个的方法和属性 Console.WriteLine("创建对象的方法 们"); MethodInfo[] mes= A_GetMethods(objB); ShowMethods(mes); Console.WriteLine(); Console.WriteLine("创建对象的方法 "); MethodInfo[] me = B_GetMethod(objB,"SayHello"); ShowMethods(me); Console.WriteLine(); Console.WriteLine("创建对象的属性 们"); PropertyInfo[] pros = A_GetProperties(objB); ShowProperties(pros); Console.WriteLine(); Console.WriteLine("创建对象的属性"); PropertyInfo[] pro = B_GetProperty(objB,"Age"); ShowProperties(pro); Console.WriteLine(); //调用方法的值 Console.WriteLine("调用创建对象的SayHello方法"); me[0].Invoke(objB, null); Console.WriteLine(); //获得Age属性的值 Console.WriteLine("获得Age属性的值"); pro[0].SetValue(objB,55); Console.WriteLine(pro[0].GetValue(objB)); } Console.Read(); } #region 01加载程序集 public static Assembly LoadAssembly() { //01 注意是绝对路径 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll"); //02 加载程序集 return Assembly.LoadFile(path); } #endregion #region 02-获取数据(abc三种常见的方法) /// <summary> /// 方法A获得程序集所有数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] A_GetTypes(Assembly ass) { Type[] types = ass.GetTypes(); return types; } /// <summary> /// 方法B获得程序集所有--public数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] B_GetExportedTypes(Assembly ass) { Type[] types = ass.GetExportedTypes(); return types; } /// <summary> /// 方法C根据数据名称获得指定数据,可以是私有的 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] C_GetType(Assembly ass) { Type atype = ass.GetType("Common.Teacher"); Type[] types = { atype }; return types; } #endregion #region 03-显示数据 private static void ShowItem(Type[] types) { foreach (var item in types) { Console.WriteLine(item.Name); } } #endregion #region 04创建对象(两种方法) /// <summary> /// 创建对象方法A,CreateInstance,注意是通过无参构造函数创建的. /// 方法B ,Activator.CreateInstance创建对象 /// </summary> /// <param name="ass"></param> /// <returns></returns> private static object A_CreateInstance(Assembly ass) { //object obj = ass.CreateInstance("Common.Student");//如果不含有 无参构造函数,会报错 object obj = ass.CreateInstance("Common.Teacher"); return obj; } /// <summary> /// 方法B ,Activator.CreateInstance创建对象 /// </summary> /// <param name="ass"></param> /// <returns></returns> private static object B_CreateInstance(Assembly ass) { //1获取创建对象的类型 Type type = ass.GetType("Common.Student"); object obj = Activator.CreateInstance(type,"张三",22); return obj; } #endregion #region 05获得创建对象的方法和属性 public static MethodInfo[] A_GetMethods(object obj) { MethodInfo[] mes = obj.GetType().GetMethods(); return mes; } public static MethodInfo[] B_GetMethod(object obj,string methodName) { MethodInfo me = obj.GetType().GetMethod(methodName); MethodInfo[] mes ={me}; return mes; } public static PropertyInfo[] A_GetProperties(object obj) { PropertyInfo [] prs = obj.GetType().GetProperties(); return prs; } public static PropertyInfo[] B_GetProperty(object obj, string proName) { PropertyInfo pr = obj.GetType().GetProperty(proName); PropertyInfo[] prs = { pr }; return prs; } #endregion #region 06获得属性方法 public static void ShowMethods(MethodInfo[] mes) { foreach (MethodInfo item in mes) { Console.WriteLine(item.Name); } } public static void ShowProperties(PropertyInfo[] pros) { foreach (PropertyInfo item in pros) { Console.WriteLine(item.Name); } } #endregion } }
仔细观察获得的方法值有SayHello公共的,没有SayHi私有的方法.而且GetMethod也无法调用私有的方法
6 反射中常用的方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
if (ass!=null) { Type[] types = A_GetTypes(ass); //此时数组中依次存在 Brid,Person,Student,Teacher四个元素 //Studnet能否 里氏转换 为Person 子类赋值给父类 bool a = types[1].IsAssignableFrom(types[2]);//true Console.WriteLine(a); //Student是否是Person的实例 Type type = ass.GetType("Common.Student"); object obj = Activator.CreateInstance(type, "张三", 22); bool b = types[1].IsInstanceOfType(obj);//true bool d = types[0].IsInstanceOfType(obj);//false Console.WriteLine(b); Console.WriteLine(d); //Teacher是否是Person的子类---没有接口 bool c = types[3].IsSubclassOf(types[1]);//true Console.WriteLine(c); //Person是否是抽象函数 bool e = types[1].IsAbstract; Console.WriteLine(e); }
运行效果
总体代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace 反射_基础 { class Program { static void Main(string[] args) { Assembly ass = LoadAssembly(); #region 获取程序集的数据 if (ass == null) { Console.WriteLine("获得所有数据"); Type[] typesA = A_GetTypes(ass); ShowItem(typesA); Console.WriteLine(); Console.WriteLine("获得所有public数据"); Type[] typesB = B_GetExportedTypes(ass); ShowItem(typesB); Console.WriteLine(); Console.WriteLine("获得指定数据,可以是私有的"); Type[] typeC = C_GetType(ass); ShowItem(typeC); //创建对象 Console.WriteLine(); Console.WriteLine("方法A创建对象(必须含有无参构造函数)"); object objA = A_CreateInstance(ass); Console.WriteLine(objA.GetType().Name); Console.WriteLine(); Console.WriteLine("方法B创建对象"); object objB = B_CreateInstance(ass); Console.WriteLine(objB.GetType().Name); Console.WriteLine(); //获得创建对象那个的方法和属性 Console.WriteLine("创建对象的方法 们"); MethodInfo[] mes = A_GetMethods(objB); ShowMethods(mes); Console.WriteLine(); Console.WriteLine("创建对象的方法 "); MethodInfo[] me = B_GetMethod(objB, "SayHello"); ShowMethods(me); Console.WriteLine(); Console.WriteLine("创建对象的属性 们"); PropertyInfo[] pros = A_GetProperties(objB); ShowProperties(pros); Console.WriteLine(); Console.WriteLine("创建对象的属性"); PropertyInfo[] pro = B_GetProperty(objB, "Age"); ShowProperties(pro); Console.WriteLine(); //调用方法的值 Console.WriteLine("调用创建对象的SayHello方法"); me[0].Invoke(objB, null); Console.WriteLine(); //获得Age属性的值 Console.WriteLine("获得Age属性的值"); pro[0].SetValue(objB, 55); Console.WriteLine(pro[0].GetValue(objB)); } #endregion //bool if (ass!=null) { Type[] types = A_GetTypes(ass); //此时数组中依次存在 Brid,Person,Student,Teacher四个元素 //Studnet能否 里氏转换 为Person 子类赋值给父类 bool a = types[1].IsAssignableFrom(types[2]);//true Console.WriteLine(a); //Student是否是Person的实例 Type type = ass.GetType("Common.Student"); object obj = Activator.CreateInstance(type, "张三", 22); bool b = types[1].IsInstanceOfType(obj);//true bool d = types[0].IsInstanceOfType(obj);//false Console.WriteLine(b); Console.WriteLine(d); //Teacher是否是Person的子类---没有接口 bool c = types[3].IsSubclassOf(types[1]);//true Console.WriteLine(c); //Person是否是抽象函数 bool e = types[1].IsAbstract; Console.WriteLine(e); } Console.Read(); } #region 01加载程序集 public static Assembly LoadAssembly() { //01 注意是绝对路径 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"Common.dll"); //02 加载程序集 return Assembly.LoadFile(path); } #endregion #region 02-获取数据(abc三种常见的方法) /// <summary> /// 方法A获得程序集所有数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] A_GetTypes(Assembly ass) { Type[] types = ass.GetTypes(); return types; } /// <summary> /// 方法B获得程序集所有--public数据类型 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] B_GetExportedTypes(Assembly ass) { Type[] types = ass.GetExportedTypes(); return types; } /// <summary> /// 方法C根据数据名称获得指定数据,可以是私有的 /// </summary> /// <param name="ass">程序集名称</param> /// <returns></returns> private static Type[] C_GetType(Assembly ass) { Type atype = ass.GetType("Common.Teacher"); Type[] types = { atype }; return types; } #endregion #region 03-显示数据 private static void ShowItem(Type[] types) { foreach (var item in types) { Console.WriteLine(item.Name); } } #endregion #region 04创建对象(两种方法) /// <summary> /// 创建对象方法A,CreateInstance,注意是通过无参构造函数创建的. /// 方法B ,Activator.CreateInstance创建对象 /// </summary> /// <param name="ass"></param> /// <returns></returns> private static object A_CreateInstance(Assembly ass) { //object obj = ass.CreateInstance("Common.Student");//如果不含有 无参构造函数,会报错 object obj = ass.CreateInstance("Common.Teacher"); return obj; } /// <summary> /// 方法B ,Activator.CreateInstance创建对象 /// </summary> /// <param name="ass"></param> /// <returns></returns> private static object B_CreateInstance(Assembly ass) { //1获取创建对象的类型 Type type = ass.GetType("Common.Student"); object obj = Activator.CreateInstance(type,"张三",22); return obj; } #endregion #region 05获得创建对象的方法和属性 public static MethodInfo[] A_GetMethods(object obj) { MethodInfo[] mes = obj.GetType().GetMethods(); return mes; } public static MethodInfo[] B_GetMethod(object obj,string methodName) { MethodInfo me = obj.GetType().GetMethod(methodName); MethodInfo[] mes ={me}; return mes; } public static PropertyInfo[] A_GetProperties(object obj) { PropertyInfo [] prs = obj.GetType().GetProperties(); return prs; } public static PropertyInfo[] B_GetProperty(object obj, string proName) { PropertyInfo pr = obj.GetType().GetProperty(proName); PropertyInfo[] prs = { pr }; return prs; } #endregion #region 06获得属性方法 public static void ShowMethods(MethodInfo[] mes) { foreach (MethodInfo item in mes) { Console.WriteLine(item.Name); } } public static void ShowProperties(PropertyInfo[] pros) { foreach (PropertyInfo item in pros) { Console.WriteLine(item.Name); } } #endregion } }
dll 放置在对应的目录下的文件夹中