标签:
基础代码:
1 public interface IDBHelper 2 { 3 void Query(); 4 } 5 public class DBHelper : IDBHelper 6 { 7 public int Id { get; set; } 8 public string Name { get; set; } 9 10 public DBHelper() 11 { 12 //Console.WriteLine("这里是{0}的无参构造函数", this.GetType().FullName); 13 } 14 15 public void Query() 16 { 17 //Console.WriteLine("这里是{0}的Query", this.GetType().FullName); 18 } 19 20 }
1. 反射加载dll,读取module
动态加载:
1 Assembly assembly = Assembly.Load("当前路径下的dll文件");// 默认加载当前路径的dll文件,不需要后缀 2 Assembly assembly1 = Assembly.LoadFile("完整路径");// 必须是完整路径-需要后缀.dll 3 Assembly assembly2 = Assembly.LoadFrom("当前路径|或者是完整路径");// 可以是当前路径 也可以是完整路径-需要后缀.dll
2. 读取module、类、方法
1 Console.WriteLine("************GetModules**********"); 2 foreach (var item in assembly.GetModules()) 3 { 4 Console.WriteLine(item.FullyQualifiedName); 5 } 6 foreach (var item in assembly.GetTypes()) 7 { 8 Console.WriteLine(item.FullName); 9 } 10 Type typeDBHelper = assembly.GetType("Ruanmou.DB.Sqlserver.DBHelper");//2 获取类型-指定名称获取类型 11 foreach (var item in typeDBHelper.GetConstructors()) 12 { 13 Console.WriteLine(item.Name); 14 } 15 foreach (var item in typeDBHelper.GetProperties()) 16 { 17 Console.WriteLine(item.Name); 18 } 19 foreach (var item in typeDBHelper.GetMethods()) 20 { 21 Console.WriteLine(item.Name); 22 } 23 foreach (var item in typeDBHelper.GetFields()) 24 { 25 Console.WriteLine(item.Name); 26 }
3.简单工厂:
配置文件:
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <startup> 4 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 5 </startup> 6 <appSettings> 7 <add key="IDBHelper" value="Ruanmou.DB.Sqlserver.DBHelper,Ruanmou.DB.Sqlserver"/> 8 </appSettings> 9 </configuration>
1 public class SimpleFactory 2 { 3 private static string IDBHelperConfig = ConfigurationManager.AppSettings["IDBHelper"]; 4 5 public static IDBHelper CreateDBHelper() 6 { 7 string dllName = IDBHelperConfig.Split(‘,‘)[1]; 8 string className = IDBHelperConfig.Split(‘,‘)[0]; 9 10 Assembly assembly = Assembly.Load(dllName); 11 Type type = assembly.GetType(className); 12 object oObject = Activator.CreateInstance(type); 13 return (IDBHelper)oObject; 14 15 } 16 }
对比一下,个人感觉就是封装了一下.不过用起来很方便的啦!
Console.WriteLine("**************************************************"); { object oDBHelper = Activator.CreateInstance(typeDBHelper);// 创建对象 IDBHelper dbHelperReflection = (IDBHelper)oDBHelper; dbHelperReflection.Query(); //简单工厂 IDBHelper dbHelperFactory = SimpleFactory.CreateDBHelper(); dbHelperFactory.Query(); }
4.反射创建对象,反射+简单工厂+配置文件. ------------------ 破坏单例 创建泛型
1 namespace Ruanmou.DB.Sqlserver 2 { 3 /// <summary> 4 /// 反射测试类 5 /// </summary> 6 public class ReflectionTest 7 { 8 public int Id { get; set; } 9 public string Name { get; set; } 10 11 public string Field = null; 12 public static string FieldStatic = null; 13 14 15 #region 构造函数 16 public ReflectionTest() 17 { 18 Console.WriteLine("这里是{0}无参数构造函数", this.GetType()); 19 } 20 21 public ReflectionTest(string name) 22 { 23 Console.WriteLine("这里是{0} 有参数构造函数", this.GetType()); 24 } 25 26 public ReflectionTest(int id, string name) 27 { 28 Console.WriteLine("这里是{0} 有参数构造函数", this.GetType()); 29 } 30 #endregion 31 32 public static void ShowStatic(string name) 33 { 34 Console.WriteLine("这里是{0}的ShowStatic", typeof(ReflectionTest)); 35 } 36 37 public void ShowGeneric<T>(string name) 38 { 39 Console.WriteLine("这里是{0}的ShowStatic T={1}", this.GetType(), typeof(T)); 40 } 41 42 public void Show1() 43 { 44 Console.WriteLine("这里是{0}的Show1", this.GetType()); 45 } 46 47 public void Show2(int id) 48 { 49 50 Console.WriteLine("这里是{0}的Show2", this.GetType()); 51 } 52 53 public void Show3() 54 { 55 Console.WriteLine("这里是{0}的Show3_1", this.GetType()); 56 } 57 58 public void Show3(int id, string name) 59 { 60 Console.WriteLine("这里是{0}的Show3", this.GetType()); 61 } 62 63 public void Show3(string name, int id) 64 { 65 Console.WriteLine("这里是{0}的Show3_2", this.GetType()); 66 } 67 68 public void Show3(int id) 69 { 70 71 Console.WriteLine("这里是{0}的Show3_3", this.GetType()); 72 } 73 74 public void Show3(string name) 75 { 76 77 Console.WriteLine("这里是{0}的Show3_4", this.GetType()); 78 } 79 80 private void Show4(string name) 81 { 82 Console.WriteLine("这里是{0}的Show4", this.GetType()); 83 } 84 85 } 86 }
1 /// <summary> 2 /// 单例模式 3 /// </summary> 4 public sealed class Singleton 5 { 6 private Singleton() 7 { 8 Console.WriteLine("初始化一次"); 9 } 10 11 private static Singleton Instance = new Singleton(); 12 13 public static Singleton CreateInstance() 14 { 15 return Instance; 16 } 17 }
单例就是一个类只有一个实例
对构造函数的调用:
反射创建实例时,要指定类型.然后再指定构造函数的参数.
1 { 2 Console.WriteLine("**************带参数的构造函数****************"); 3 Type typeTest = assembly.GetType("Ruanmou.DB.Sqlserver.ReflectionTest"); 4 foreach (var item in typeTest.GetConstructors()) 5 { 6 Console.WriteLine(item.Name); 7 } 8 Activator.CreateInstance(typeTest); 9 Activator.CreateInstance(typeTest, "demon"); 10 Activator.CreateInstance(typeTest, 11, "限量版(397-限量版)"); 11 //Activator.CreateInstance(typeTest, "限量版(397-限量版)", 11);---这里调用时将两个不同类型的参数位置放置错误,导致错误.所以注释了. 12 13 //该反射破坏了单例 14 Type typeSingleton = assembly.GetType("Ruanmou.DB.Sqlserver.Singleton"); 15 Activator.CreateInstance(typeSingleton, true); 16 Activator.CreateInstance(typeSingleton, true); 17 //泛型 18 Type typeGeneric = assembly.GetType("Ruanmou.DB.Sqlserver.GenericClass`1"); 19 typeGeneric = typeGeneric.MakeGenericType(typeof(int));//反射调用泛型时指定类型的方法 20 Activator.CreateInstance(typeGeneric); 21 }
5. 反射调用实例方法、静态方法、重载方法 -------------调用私有方法 调用泛型方法(这个666)
1 Console.WriteLine("**************反射调用实例方法****************"); 2 Type typeTest = assembly.GetType("Ruanmou.DB.Sqlserver.ReflectionTest"); 3 object oTest = Activator.CreateInstance(typeTest); 4 5 foreach (var item in typeTest.GetMethods()) 6 { 7 Console.WriteLine(item.Name); 8 } 9 { 10 MethodInfo method = typeTest.GetMethod("Show1"); 11 method.Invoke(oTest, null); 12 } 13 { 14 MethodInfo method = typeTest.GetMethod("Show2"); 15 method.Invoke(oTest, new object[] { 11 });//调用方法时第一个参数指定实例 16 } 17 { 18 MethodInfo method = typeTest.GetMethod("ShowStatic"); 19 method.Invoke(null, new object[] { "KOBE→Bryant" });//静态方法的第一个参数为null-是因为静态方法的调用不需要指定实例 20 }
//以下对应不同的重载方法: 21 { 22 MethodInfo method = typeTest.GetMethod("Show3", new Type[] { }); 23 method.Invoke(oTest, null); 24 } 25 { 26 MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(int) }); 27 method.Invoke(oTest, new object[] { 11 }); 28 } 29 { 30 MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(string) }); 31 method.Invoke(oTest, new object[] { "限量版(397-限量版)" }); 32 } 33 { 34 MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(string), typeof(int) }); 35 method.Invoke(oTest, new object[] { "书呆熊@拜仁", 22 }); 36 } 37 { 38 MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(int), typeof(string) }); 39 method.Invoke(oTest, new object[] { 33, "不懂微软" }); 40 }
//除了参数,指定控制绑定和由反射执行的成员和类型搜索方法的标志,可以调用私有方法. 41 { 42 MethodInfo method = typeTest.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic); 43 method.Invoke(oTest, new object[] { "有木有" }); 44 } 45 { 46 MethodInfo method = typeTest.GetMethod("ShowGeneric"); 47 method = method.MakeGenericMethod(typeof(string)); 48 method.Invoke(oTest, new object[] { "有木有" }); 49 }
6. 反射字段和属性,分别获取值和设置值
1 Console.WriteLine("**************反射字段和属性****************"); 2 ReflectionTest test = new ReflectionTest(); 3 test.Id = 11; 4 test.Name = "妙为"; 5 6 Type typeTest = assembly.GetType("Ruanmou.DB.Sqlserver.ReflectionTest"); 7 object oTest = Activator.CreateInstance(typeTest); 8 //foreach (var item in typeTest.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) 9 //{ 10 // Console.WriteLine(item.Name); 11 //} 12 foreach (var prop in typeTest.GetProperties()) 13 { 14 Console.WriteLine(prop.GetValue(oTest)); 15 Console.WriteLine(prop.Name); 16 if (prop.Name.Equals("Id")) 17 { 18 prop.SetValue(oTest, 22); 19 } 20 else if (prop.Name.Equals("Name")) 21 { 22 prop.SetValue(oTest, "Bond(331-object)"); 23 } 24 25 Console.WriteLine(prop.GetValue(oTest)); 26 }
7. 反射的好处和局限 好处就是动态
1 { 2 Stopwatch watch = new Stopwatch(); 3 watch.Start(); 4 for (int i = 0; i < 100000; i++) 5 { 6 DBHelper dbHelper = new DBHelper(); 7 dbHelper.Id = 1; 8 dbHelper.Name = "仗劍走天涯"; 9 dbHelper.Query(); 10 } 11 watch.Stop(); 12 Console.WriteLine("普通方式花费{0}ms", watch.ElapsedMilliseconds); 13 } 14 { 15 Stopwatch watch = new Stopwatch(); 16 watch.Start(); 17 for (int i = 0; i < 100000; i++) 18 { 19 Assembly assemblyTest = Assembly.Load("Ruanmou.DB.Sqlserver"); 20 21 Type typeTest = assemblyTest.GetType("Ruanmou.DB.Sqlserver.DBHelper"); 22 object oTest = Activator.CreateInstance(typeTest); 23 24 foreach (var prop in typeTest.GetProperties()) 25 { 26 if (prop.Name.Equals("Id")) 27 { 28 prop.SetValue(oTest, 1); 29 } 30 else if (prop.Name.Equals("Name")) 31 { 32 prop.SetValue(oTest, "仗劍走天涯"); 33 } 34 } 35 MethodInfo method = typeTest.GetMethod("Query"); 36 method.Invoke(oTest, null); 37 } 38 watch.Stop(); 39 Console.WriteLine("反射方式花费{0}ms", watch.ElapsedMilliseconds); 40 }
局限:避开了编译器的检查,运行时错误才会暴露出来.(如果有的话)
性能损耗
标签:
原文地址:http://www.cnblogs.com/anwser-jungle/p/5918464.html