温故知新之:反射:加载程序集中的类,动态调用

  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的类型信息。

 

posted @ 2020-02-12 05:22  钢的锅  阅读(220)  评论(0编辑  收藏  举报