温故知新之:反射:加载程序集中的类,动态调用
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Reflection; 5 using System.Text; 6 7 //Net Reflector(收费)官方网址:http://www.red-gate.com/products/dotnet-development/reflector/ 8 //ILSpy/dnSpy 【免费】官方网址:http://ilspy.net/ 9 //https://www.cnblogs.com/ldc218/p/8945892.html 推荐.Net、C# 逆向反编译四大工具利器 https://blog.csdn.net/kongwei521/article/details/54927689 10 11 12 //我们拿到一个别人写的程序集,可以用用各种反编译工具来分析其内部代码,也可以自己写代码来反射调用其内部代码: 13 14 namespace 得到程序集 15 { 16 class Program 17 { 18 static void Main(string[] args) 19 { 20 Assembly[] Masms = AppDomain.CurrentDomain.GetAssemblies(); // 得到所有该程序加载的程序集 21 //GetInfoFromAssembl(Masms);// 将产生大量的东西 22 //从路径加载 23 //string MfilePath = @"D:\201205Demos\反射案例、Attribute\测试程序集1\bin\Debug\测试程序集1.dll"; 24 25 26 string MfilePath = @"C:\Users\Administrator\source\repos\温故知新\测试程序集\bin\Debug\netstandard2.0\测试程序集.dll"; 27 Assembly Masm = Assembly.LoadFile(MfilePath); 28 GetInfoFromAssembl(new Assembly[] { Masm }); 29 //CreateInstanceFromAssembly(Masm); 30 31 Console.ReadKey(); 32 } 33 /// <summary> 34 /// 从程序集Assembly中获取信息 35 /// </summary> 36 /// <param name="Pasms"></param> 37 static void GetInfoFromAssembl(Assembly[] Pasms) 38 { 39 foreach (Assembly Masm in Pasms) 40 { 41 Console.WriteLine("Location ======{0}", Masm.Location); 42 Console.WriteLine("FullName ======{0}", Masm.FullName); 43 GetInfoFromAssemblSub(Masm); 44 } 45 } 46 /// <summary> 47 /// 从程序集中获取类的信息,几乎都可以获得,这里只获得属性和方法 48 /// </summary> 49 /// <param name="Pasm"></param> 50 private static void GetInfoFromAssemblSub(Assembly Pasm) 51 { 52 Type[] Mtypes = Pasm.GetTypes();//获得所加载程序集所有的类 53 //Type[] Mtypes = Pasm.GetExportedTypes();//获得所加载程序集public类 54 foreach (Type Mtype in Mtypes) 55 { 56 Console.WriteLine("Type ============================================================== {0}",Mtype); 57 58 //PropertyInfo[] props = Mtype.GetProperties();//获得程序集所有的public属性 59 PropertyInfo[] props = Mtype.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);//获得程序集所有的private属性 60 //FieldInfo[] props = Mtype.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 61 foreach (PropertyInfo prop in props) 62 { 63 Console.WriteLine("PropertyInfo:{0}", prop); 64 } 65 66 //MethodInfo[] methods = Mtype.GetMethods();//获得程序集所有的public方法 67 68 MethodInfo[] methods = Mtype.GetMethods(BindingFlags.NonPublic|BindingFlags.Instance);//查找所有私有方法 69 foreach (MethodInfo m in methods) 70 { 71 Console.WriteLine(m); 72 } 73 74 //MethodInfo methodInfo = Mtype.GetMethod("Wife"); 75 MethodInfo methodInfo = Mtype.GetMethod("Wife",BindingFlags.NonPublic | BindingFlags.Instance);//得到特定的私有方法 76 //Console.WriteLine(methodInfo); 77 78 79 CreateInstanceFromAssembly(Mtype); 80 81 } 82 } 83 /// <summary> 84 /// 根据一个类型,创建一个实例 85 /// </summary> 86 /// <param name="Passembly"></param> 87 private static void CreateInstanceFromAssembly(Type Ptype) 88 { 89 var Mobj = Activator.CreateInstance(Ptype);// 创建一个实例 90 91 92 PropertyInfo propAge = Ptype.GetProperty("Age");//获得person类的age属性的描述(与实例无关) 93 if (propAge != null) 94 { 95 propAge.SetValue(Mobj, 27, null);//第一个参数 要为哪个对象的age属性赋值 96 PropertyInfo propName = Ptype.GetProperty("Name"); 97 propName.SetValue(Mobj, "tom", null); 98 //调用方法 99 MethodInfo methodsayhello = Ptype.GetMethod("SayHello"); 100 methodsayhello.Invoke(Mobj, null); 101 102 MethodInfo methodWife = Ptype.GetMethod("Wife", BindingFlags.NonPublic | BindingFlags.Instance);//得到特定的私有方法 103 methodWife.Invoke(Mobj, new object[] { "苍井空" }); 104 } 105 106 } 107 } 108 } 109 110 111 //namespace 测试程序集 112 //{ 113 // public class Person 114 // { 115 // public Person() 116 // { Console.WriteLine("创建了一个人"); } 117 // public string Name { get; set; } 118 // public int Age { get; set; } 119 // private int Gender { get; set; } 120 // public void SayHello() 121 // { 122 // Console.WriteLine("My name is {0} and {1} years old", Name, Age); 123 // } 124 // private void Wife() 125 // { 126 // Console.WriteLine("Wife is private!"); 127 // } 128 // } 129 130 131 //class TokyoHot 132 //{ 133 // public TokyoHot() 134 // { Console.WriteLine("Tokyo Hot is private"); } 135 //} 136 137 //} 138 139 140 //获得Type对象的方法: 141 //通过类获得Type:Type t = typeof(Person) 142 //通过对象获得类的Type:Type t = p.GetType() 143 //调用Assembly的GetExportedTypes方法可以得到Assembly中定义的所有的public类型。 144 //调用Assembly的GetTypes()方法可以得到Assembly中定义的所有的类型。 145 //调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息。