using System.Reflection;
基础代码:
public interface IDBHelper { void Query(); } public class DBHelper : IDBHelper { public int Id { get; set; } public string Name { get; set; } public DBHelper() { //Console.WriteLine("这里是{0}的无参构造函数", this.GetType().FullName); } public void Query() { //Console.WriteLine("这里是{0}的Query", this.GetType().FullName); } }
1. 反射加载dll,读取module
动态加载:
Assembly assembly = Assembly.Load("当前路径下的dll文件");// 默认加载当前路径的dll文件,不需要后缀 Assembly assembly1 = Assembly.LoadFile("完整路径");// 必须是完整路径-需要后缀.dll Assembly assembly2 = Assembly.LoadFrom("当前路径|或者是完整路径");// 可以是当前路径 也可以是完整路径-需要后缀.dll
2. 读取module、类、方法
Console.WriteLine("************GetModules**********"); foreach (var item in assembly.GetModules()) { Console.WriteLine(item.FullyQualifiedName); } foreach (var item in assembly.GetTypes()) { Console.WriteLine(item.FullName); } Type typeDBHelper = assembly.GetType("Ruanmou.DB.Sqlserver.DBHelper");//2 获取类型-指定名称获取类型 foreach (var item in typeDBHelper.GetConstructors()) { Console.WriteLine(item.Name); } foreach (var item in typeDBHelper.GetProperties()) { Console.WriteLine(item.Name); } foreach (var item in typeDBHelper.GetMethods()) { Console.WriteLine(item.Name); } foreach (var item in typeDBHelper.GetFields()) { Console.WriteLine(item.Name); }
3.简单工厂:
配置文件:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <appSettings> <add key="IDBHelper" value="Ruanmou.DB.Sqlserver.DBHelper,Ruanmou.DB.Sqlserver"/> </appSettings> </configuration>
public class SimpleFactory { private static string IDBHelperConfig = ConfigurationManager.AppSettings["IDBHelper"]; public static IDBHelper CreateDBHelper() { ]; ]; Assembly assembly = Assembly.Load(dllName); Type type = assembly.GetType(className); object oObject = Activator.CreateInstance(type); return (IDBHelper)oObject; } }
对比一下,个人感觉就是封装了一下.不过用起来很方便的啦!
Console.WriteLine("**************************************************"); { object oDBHelper = Activator.CreateInstance(typeDBHelper);// 创建对象 IDBHelper dbHelperReflection = (IDBHelper)oDBHelper; dbHelperReflection.Query(); //简单工厂 IDBHelper dbHelperFactory = SimpleFactory.CreateDBHelper(); dbHelperFactory.Query(); }
4.反射创建对象,反射+简单工厂+配置文件. ------------------ 破坏单例 创建泛型
namespace Ruanmou.DB.Sqlserver { /// <summary> /// 反射测试类 /// </summary> public class ReflectionTest { public int Id { get; set; } public string Name { get; set; } public string Field = null; public static string FieldStatic = null; #region 构造函数 public ReflectionTest() { Console.WriteLine("这里是{0}无参数构造函数", this.GetType()); } public ReflectionTest(string name) { Console.WriteLine("这里是{0} 有参数构造函数", this.GetType()); } public ReflectionTest(int id, string name) { Console.WriteLine("这里是{0} 有参数构造函数", this.GetType()); } #endregion public static void ShowStatic(string name) { Console.WriteLine("这里是{0}的ShowStatic", typeof(ReflectionTest)); } public void ShowGeneric<T>(string name) { Console.WriteLine("这里是{0}的ShowStatic T={1}", this.GetType(), typeof(T)); } public void Show1() { Console.WriteLine("这里是{0}的Show1", this.GetType()); } public void Show2(int id) { Console.WriteLine("这里是{0}的Show2", this.GetType()); } public void Show3() { Console.WriteLine("这里是{0}的Show3_1", this.GetType()); } public void Show3(int id, string name) { Console.WriteLine("这里是{0}的Show3", this.GetType()); } public void Show3(string name, int id) { Console.WriteLine("这里是{0}的Show3_2", this.GetType()); } public void Show3(int id) { Console.WriteLine("这里是{0}的Show3_3", this.GetType()); } public void Show3(string name) { Console.WriteLine("这里是{0}的Show3_4", this.GetType()); } private void Show4(string name) { Console.WriteLine("这里是{0}的Show4", this.GetType()); } } }
/// <summary> /// 单例模式 /// </summary> public sealed class Singleton { private Singleton() { Console.WriteLine("初始化一次"); } private static Singleton Instance = new Singleton(); public static Singleton CreateInstance() { return Instance; } }
单例就是一个类只有一个实例
对构造函数的调用:
反射创建实例时,要指定类型.然后再指定构造函数的参数.
{ Console.WriteLine("**************带参数的构造函数****************"); Type typeTest = assembly.GetType("Ruanmou.DB.Sqlserver.ReflectionTest"); foreach (var item in typeTest.GetConstructors()) { Console.WriteLine(item.Name); } Activator.CreateInstance(typeTest); 9 Activator.CreateInstance(typeTest, "demon"); 10 Activator.CreateInstance(typeTest, 11, "限量版(397-限量版)"); //Activator.CreateInstance(typeTest, "限量版(397-限量版)", 11);---这里调用时将两个不同类型的参数位置放置错误,导致错误.所以注释了. //该反射破坏了单例 Type typeSingleton = assembly.GetType("Ruanmou.DB.Sqlserver.Singleton"); Activator.CreateInstance(typeSingleton, true); Activator.CreateInstance(typeSingleton, true); //泛型 Type typeGeneric = assembly.GetType("Ruanmou.DB.Sqlserver.GenericClass`1"); typeGeneric = typeGeneric.MakeGenericType(typeof(int));//反射调用泛型时指定类型的方法 Activator.CreateInstance(typeGeneric); }
5. 反射调用实例方法、静态方法、重载方法 -------------调用私有方法 调用泛型方法(这个666)
Console.WriteLine("**************反射调用实例方法****************"); Type typeTest = assembly.GetType("Ruanmou.DB.Sqlserver.ReflectionTest"); object oTest = Activator.CreateInstance(typeTest); foreach (var item in typeTest.GetMethods()) { Console.WriteLine(item.Name); } { MethodInfo method = typeTest.GetMethod("Show1"); method.Invoke(oTest, null); } { MethodInfo method = typeTest.GetMethod("Show2"); method.Invoke( });//调用方法时第一个参数指定实例 } { MethodInfo method = typeTest.GetMethod("ShowStatic"); method.Invoke(null, new object[] { "KOBE→Bryant" });//静态方法的第一个参数为null-是因为静态方法的调用不需要指定实例 } //以下对应不同的重载方法: { MethodInfo method = typeTest.GetMethod("Show3", new Type[] { }); method.Invoke(oTest, null); } { MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(int) }); method.Invoke(oTest, new object[] { 11 }); } { MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(string) }); method.Invoke(oTest, new object[] { "限量版(397-限量版)" }); } { MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(string), typeof(int) }); method.Invoke(oTest, new object[] { "书呆熊@拜仁", 22 }); } { MethodInfo method = typeTest.GetMethod("Show3", new Type[] { typeof(int), typeof(string) }); method.Invoke(oTest, new object[] { 33, "不懂微软" }); } //除了参数,指定控制绑定和由反射执行的成员和类型搜索方法的标志,可以调用私有方法. { MethodInfo method = typeTest.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(oTest, new object[] { "有木有" }); } { MethodInfo method = typeTest.GetMethod("ShowGeneric"); method = method.MakeGenericMethod(typeof(string)); method.Invoke(oTest, new object[] { "有木有" }); }
6. 反射字段和属性,分别获取值和设置值
Console.WriteLine("**************反射字段和属性****************"); ReflectionTest test = new ReflectionTest(); test.Id = ; test.Name = "妙为"; Type typeTest = assembly.GetType("Ruanmou.DB.Sqlserver.ReflectionTest"); object oTest = Activator.CreateInstance(typeTest); //foreach (var item in typeTest.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) //{ // Console.WriteLine(item.Name); //} foreach (var prop in typeTest.GetProperties()) { Console.WriteLine(prop.GetValue(oTest)); Console.WriteLine(prop.Name); if (prop.Name.Equals("Id")) { prop.SetValue(oTest, ); } else if (prop.Name.Equals("Name")) { prop.SetValue(oTest, "Bond(331-object)"); } Console.WriteLine(prop.GetValue(oTest)); }
7. 反射的好处和局限 好处就是动态
{ Stopwatch watch = new Stopwatch(); watch.Start(); ; i < ; i++) { DBHelper dbHelper = new DBHelper(); dbHelper.Id = ; dbHelper.Name = "仗劍走天涯"; dbHelper.Query(); } watch.Stop(); Console.WriteLine("普通方式花费{0}ms", watch.ElapsedMilliseconds); } { Stopwatch watch = new Stopwatch(); watch.Start(); ; i < ; i++) { Assembly assemblyTest = Assembly.Load("Ruanmou.DB.Sqlserver"); Type typeTest = assemblyTest.GetType("Ruanmou.DB.Sqlserver.DBHelper"); object oTest = Activator.CreateInstance(typeTest); foreach (var prop in typeTest.GetProperties()) { if (prop.Name.Equals("Id")) { prop.SetValue(oTest, ); } else if (prop.Name.Equals("Name")) { prop.SetValue(oTest, "仗劍走天涯"); } } MethodInfo method = typeTest.GetMethod("Query"); method.Invoke(oTest, null); } watch.Stop(); Console.WriteLine("反射方式花费{0}ms", watch.ElapsedMilliseconds); }
局限:避开了编译器的检查,运行时错误才会暴露出来.(如果有的话)
性能损耗
using System.Reflection;的更多相关文章
- Could not load type 'System.Reflection.AssemblySignatureKeyAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c
错误: Could not load type 'System.Reflection.AssemblySignatureKeyAttribute' from assembly 'mscorlib, V ...
- 异常:“System.Reflection.Metadata”已拥有为“System.Collections.Immutable”定义的依赖项
参考动态执行T4模板:https://msdn.microsoft.com/zh-cn/library/bb126579.aspx 我项目是.NET Framework 4.5控制台应用程序写的. 执 ...
- 【C#基础】System.Reflection (反射)
在使用.NET创建的程序或组件时,元数据(metadata)和代码(code)都存储于"自成一体"的单元中,这个单元称为装配件.我们可以在程序运行期间访问这些信息.在System. ...
- [转]System.Reflection.AssemblySignatureKeyAttribute
转自:http://www.cnblogs.com/ego/p/3321122.html 错误: Could not load type 'System.Reflection.AssemblySign ...
- System.Reflection.Assembly.GetEntryAssembly()获取的为当前已加载的程序集
今天在使用System.Reflection.Assembly.GetEntryAssembly()获取程序集时,发现获取的程序集不全.原来是因为C#的程序集为延迟加载,此方法只获取当前已加载的,未加 ...
- 参数计数不匹配,未处理System.Reflection.TargetParameterCountException
系统出现异常:参数计数不匹配,未处理System.Reflection.TargetParameterCountException, 系统会显示如下的异常信息,但异常信息往往与实际异常位置差十万八千量 ...
- 基础命名空间:反射 using System.Reflection
反射概念: .Net的应用程序由几个部分:‘程序集(Assembly)’.‘模块(Module)’.‘类型(class)’组成,程序集包含模块 模块包含类型,类型又包含 成员,而反射提供一 ...
- 序列化类型为“System.Reflection.Module”的对象时检测到循环引用
在使用ajax调用web services时,正好返回的类型为datatable,想用通过json方式直接解析,但调用后,得到如下错误: 序列化类型为“System.Reflection.Module ...
- System.Reflection.Emit学习
C#反射发出System.Reflection.Emit学习 分享: 1 一.System.Reflection.Emit概述 Emit,可以称为发出或者产生.与Emit相关的类基本都存在于Syste ...
- “System.Reflection.AmbiguousMatchException”类型的异常在 mscorlib.dll 中发生
错误提示: “System.Reflection.AmbiguousMatchException”类型的异常在 mscorlib.dll 中发生,但未在用户代码中进行处理. 发现不明确的匹配. 问题原 ...
随机推荐
- Ribbon 窗体的 MDI 子窗体使用 TabbedMDIManager 切换时工具条闪屏问题的解决办法
补充说明: 此问题已经在新版本中解决(15.2.6),方法更加简单,只需要在 MDIChild 窗体的 Create 方法中,将 Ribbon 的 Visible 属性设置为 false 就可以了,且 ...
- 【WinForm】使用NSIS发布程序
简介 NSIS(Nullsoft Scriptable Install System)是一个开源的 Windows 系统下安装程序制作程序.它提供了安装.卸载.系统设置.文件解压缩等功能 使用 以下是 ...
- 从零开始学android开发-布局中 layout_gravity、gravity、orientation、layout_weight
线性布局中,有 4 个及其重要的参数,直接决定元素的布局和位置,这四个参数是 android:layout_gravity ( 是本元素相对于父元素的重力方向 ) android:gravity (是 ...
- 也谈OpenFlow, SDN, NFV
Copyright (2014) 郭龙仓. All Rights Reserved. OpenFlow 传统的网络环境中,仅仅有路由器/交换机之间的接口/协议是标准化的,可是在网络设备内部,数据平面和 ...
- javascript操作
1. >> 按位右移运算符 result = expression1 >> expression2 右移表达式的位,保持符号不变. >> 运算符将 expressi ...
- Haproxy+MYSQL 负载均衡 原创
[root@monitor app1]# yum install haproxy Loaded plugins: security : epel | : epel/primary_db | : ext ...
- python_基本语法
初试牛刀 假设你希望学习Python这门语言,却苦于找不到一个简短而全面的入门教程.那么本教程将花费十分钟的时间带你走入Python的大门.本文的内容介于教程(Toturial)和速查手册(Cheat ...
- Linux c编程实例_例子
例一:字符与整型变量的实现 #include <stdio.h> int main() { int c1,c2; char c3; c1='a'-'A'; c2='b'-'B'; c3=; ...
- 关于mybatis用mysql时,插入返回自增主键的问题
公司决定新项目用mybatis,虽然这个以前学过但是一直没用过都忘得差不多了,而且项目比较紧,也没时间去系统点的学一学,只好很粗略的百度达到能用的程度就行了. 其中涉及到插入实体要求返回主键id的问题 ...
- Java作业代写
作业一 试用java编写一个九九乘法表并打印. 作业二: 设计两个人类与书类,并设置两者的关系,试用人去找书,书去找人,假如某人有一个儿子,它也有一本书,试用儿子去找书,书找儿子. 大作业 熟悉QQ农 ...