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     }

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                 }

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

性能损耗

时间: 2024-12-22 01:45:42

using System.Reflection;的相关文章

参数计数不匹配,未处理System.Reflection.TargetParameterCountException

系统出现异常:参数计数不匹配,未处理System.Reflection.TargetParameterCountException, 系统会显示如下的异常信息,但异常信息往往与实际异常位置差十万八千量: 未处理 System.Reflection.TargetParameterCountException Message=参数计数不匹配. Source=mscorlib StackTrace: 在 System.Reflection.RuntimeMethodInfo.Invoke(Object

【C#基础】System.Reflection (反射)

在使用.NET创建的程序或组件时,元数据(metadata)和代码(code)都存储于"自成一体"的单元中,这个单元称为装配件.我们可以在程序运行期间访问这些信息.在System.Reflection中有这样一个class----Assembly,我们可以通过它来加载一个装配件.方法如下:Assembly assm=Assembly.LoadFrom(fileName);其中filename是要加载的装配件的文件名称(带路径).接下来,我们就可以通过使用System.Reflectio

C# System.Reflection (反射)

在使用.NET创建的程序或组件时,元数据(metadata)和代码(code)都存储于"自成一体"的单元中,这个单元称为装配件.我们可以在程序运行期间访问这些信息. 在System.Reflection中有这样一个class----Assembly,我们可以通过它来加载一个装配件.方法如下: Assembly assm=Assembly.LoadFrom(fileName); 其中filename是要加载的装配件的文件名称(带路径). 接下来,我们就可以通过使用System.Refle

c#中system.reflection反射的使用

簡單理解為:取得已經封裝的好的dll格式程式集里的所有方法和屬性. 步驟如下: 1.Assembly ass = Assembly.LoadFrom("路徑+程式名稱"); //如 C:\\NWEEPI.DLL ; 加载程序集,返回类型是一个Assembly 2.Type t = ass.GetType(dtDLL.Rows[0]["namespace"].ToString() + "." + dtDLL.Rows[0]["classn

异常:“System.Reflection.Metadata”已拥有为“System.Collections.Immutable”定义的依赖项

参考动态执行T4模板:https://msdn.microsoft.com/zh-cn/library/bb126579.aspx 我项目是.NET Framework 4.5控制台应用程序写的. 执行用例提示报错:Microsoft.CodeAnalysis未引用,如图截图 项目引用的Microsoft.VisualStudio.TextTemplating.14.0 版本是14.3.25407 在Nuget官网上只找到 Microsoft.CodeAnalysis版本为1.3.0-beta1

EntityFramework动态创建模型:System.Reflection.Emit + Code First

动态创建Entity Framework模型并且创建数据库 使用System.Reflection.Emit+Code First model创建以下的一个实体类和DbContext并且创建数据库: 1 using System; 2 3 public class Blog 4 5 { 6 7 private int id; 8 9 private string name; 10 11 public int ID 12 13 { 14 15 get 16 17 { 18 19 return th

System.Reflection.Emit学习

C#反射发出System.Reflection.Emit学习 分享: 1 一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于System.Reflection.Emit命名空间下.反射,我们可以取得形如程序集包含哪些类型,类型包含哪些方法等等大量的信息,而Emit则可以在运行时动态生成代码. 二.IL代码解析 以下代码为例: 1 static void Main(string[] args) 2 { 3 int i = 1; 4

Error CS0579 Duplicate &#39;System.Reflection.AssemblyTitleAttribute&#39; attribute

今天在引入ClassLibraryQikuo的时候突然报错 Error CS0579 Duplicate 'System.Reflection.AssemblyTitleAttribute' attribute 然后用text文本打开.csproj文件后添加代码成 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFr

[1]System.Reflection.Emit

在这个大数据/云计算/人工智能研发普及的时代,Python的崛起以及Javascript的前后端的侵略,程序员与企业似乎越来越青睐动态语言所带来的便捷性与高效性,即使静态语言在性能,错误检查等方面的优于静态语言.对于.NETer来说,.NET做为一门静态语言,我们不仅要打好.NET的基本功,如基本类型/语法/底层原理/错误检查等知识,也要深入理解.NET的一些高级特性,来为你的工作减轻负担和提高代码质量. ok,咱们今天开始聊一聊.NET中的Emit. 一.什么是Emit? Emit含义为发出.

System.Reflection.Binder.cs

ylbtech-System.Reflection.Binder.cs 1.返回顶部 1. #region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 // C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\mscorlib.dll #endregion usin