首页 > 代码库 > using System.Reflection;

using System.Reflection;

基础代码:

技术分享
 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     }
View Code

1. 反射加载dll,读取module

动态加载:

1           Assembly assembly = Assembly.Load("当前路径下的dll文件");// 默认加载当前路径的dll文件,不需要后缀2                 Assembly assembly1 = Assembly.LoadFile("完整路径");// 必须是完整路径-需要后缀.dll3                 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=http://www.mamicode.com/"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         #endregion31 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 }
View Code
 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                 }

局限:避开了编译器的检查,运行时错误才会暴露出来.(如果有的话)

        性能损耗

 

using System.Reflection;