一、什么是反射
反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库,可以读取并使用metadata。
反射是无处不在的,MVC-Asp.Net-ORM-IOC-AOP 几乎所有的框架都离不开反射
如下图是程序执行的过程,高级语言经过编译器编译得到dll/exe文件,这里的文件可以跨平台使用,编译后的文件中其实包括了metadata元数据(数据清单,描述了DLL/exe里面的各种信息)和IL(也是一种面向对象语言,但是不太好阅读)在经过CLR/JIT编译得到可以被计算机所执行的机器码。
二、反射的使用
一)反射动态加载程序集
            Assembly assembly1 = Assembly.LoadFrom(@"DB.MySql.dll");//当前路径
Assembly assembly2 = Assembly.LoadFile(@"D:\ruanmou\MyReflection\bin\Debug\DB.MySql.dll");//dll、exe文件完整路径
Assembly assembly3 = Assembly.Load(@"DB.MySql");//dll、exe名称 dll/exe需要拷贝至程序bin文件夹下

二)简单工厂生产对应实体

        /// <summary>
/// 简单工厂生产对应实体
/// </summary>
/// <returns></returns>
public static T CreateInstance<T>()
{
Assembly assembly = Assembly.Load(ConfigurationManager.AppSettings["DalDllName"]);//加载dll
Type dalType = assembly.GetType(ConfigurationManager.AppSettings["DalTypeName"]);//获取类型
return (T)Activator.CreateInstance(dalType);//创建对象
//var newType = dalType.MakeGenericType(typeof(T));//获取泛型类型
//return (T)Activator.CreateInstance(newType);创建泛型类型对象
}

三)常用方法

            Type[] types= assembly.GetTypes();//获取程序集所有类型
Type type= assembly.GetType("TypeName");//获取指定类型
MethodInfo[] methods= type.GetMethods();//获取所有方法
MethodInfo method= type.GetMethod("methodName");//获取指定方法
PropertyInfo[] propertys= type.GetProperties();//获取所有属性
PropertyInfo property = type.GetProperty("propertyName");//获取指定属性
FieldInfo[] fields= type.GetFields();//获取所有字段
FieldInfo field = type.GetField("fieldName");//获取指定字段
Attribute attribute = type.GetCustomAttribute(typeof(DisplayNameAttribute));//获取指定特性

反射调用多参数构造函数,方法

    /// <summary>
/// 反射测试类
/// </summary>
public class ReflectionTest
{
#region Identity
/// <summary>
/// 无参构造函数
/// </summary>
public ReflectionTest()
{
Console.WriteLine("这里是{0}无参数构造函数", this.GetType());
} /// <summary>
/// 带参数构造函数
/// </summary>
/// <param name="name"></param>
public ReflectionTest(string name)
{
Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
} public ReflectionTest(int id)
{
Console.WriteLine("这里是{0} 有参数构造函数", this.GetType());
}
#endregion #region Method
/// <summary>
/// 无参方法
/// </summary>
public void Show1()
{
Console.WriteLine("这里是{0}的Show1", this.GetType());
}
/// <summary>
/// 有参数方法
/// </summary>
/// <param name="id"></param>
public void Show2(int id)
{ Console.WriteLine("这里是{0}的Show2", this.GetType());
}
/// <summary>
/// 重载方法之一
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public void Show3(int id, string name)
{
Console.WriteLine("这里是{0}的Show3", this.GetType());
}
/// <summary>
/// 重载方法之二
/// </summary>
/// <param name="name"></param>
/// <param name="id"></param>
public void Show3(string name, int id)
{
Console.WriteLine("这里是{0}的Show3_2", this.GetType());
}
/// <summary>
/// 重载方法之三
/// </summary>
/// <param name="id"></param>
public void Show3(int id)
{ Console.WriteLine("这里是{0}的Show3_3", this.GetType());
}
/// <summary>
/// 重载方法之四
/// </summary>
/// <param name="name"></param>
public void Show3(string name)
{ Console.WriteLine("这里是{0}的Show3_4", this.GetType());
}
/// <summary>
/// 重载方法之五
/// </summary>
public void Show3()
{ Console.WriteLine("这里是{0}的Show3_1", this.GetType());
}
/// <summary>
/// 私有方法
/// </summary>
/// <param name="name"></param>
private void Show4(string name)
{
Console.WriteLine("这里是{0}的Show4", this.GetType());
}
/// <summary>
/// 静态方法
/// </summary>
/// <param name="name"></param>
public static void Show5(string name)
{
Console.WriteLine("这里是{0}的Show5", typeof(ReflectionTest));
}
#endregion
}
                Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");
object oTest = Activator.CreateInstance(type);//反射调用无参数构造函数
object oTest2 = Activator.CreateInstance(type, new object[] { });//反射调用一个int类型参数构造函数
foreach (var method in type.GetMethods())
{
Console.WriteLine(method.Name);
foreach (var parameter in method.GetParameters())//获取方法参数
{
Console.WriteLine($"{parameter.Name} {parameter.ParameterType}");
}
}
{
ReflectionTest reflection = new ReflectionTest();
reflection.Show1();
}
{
MethodInfo method = type.GetMethod("Show1");
//if()
method.Invoke(oTest, null);//oTest调用无参数方法
}
{
MethodInfo method = type.GetMethod("Show2");
method.Invoke(oTest, new object[] { });//oTest调用一个int类型参数方法
}
{
MethodInfo method = type.GetMethod("Show3", new Type[] { });
method.Invoke(oTest, null);//oTest调用无参数重载方法
}
{
MethodInfo method = type.GetMethod("Show3", new Type[] { typeof(int) });
method.Invoke(oTest, new object[] { });//oTest调用一个int类型参数重载方法
} {
MethodInfo method = type.GetMethod("Show5");
method.Invoke(oTest, new object[] { "String" });//静态方法实例可以要
}
{
MethodInfo method = type.GetMethod("Show5");
method.Invoke(null, new object[] { "string" });//静态方法实例也可以不要
}
                    var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
method.Invoke(oTest, new object[] { "私有方法" });

反射调用私有方法

反射调用泛型方法、泛型类

    public class GenericClass<T, W, X>
{
public void Show(T t, W w, X x)
{
Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
}
} public class GenericMethod
{
public void Show<T, W, X>(T t, W w, X x)
{
Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
}
} public class GenericDouble<T>
{
public void Show<W, X>(T t, W w, X x)
{
Console.WriteLine("t.type={0},w.type={1},x.type={2}", t.GetType().Name, w.GetType().Name, x.GetType().Name);
}
}
               {
Console.WriteLine("********************GenericMethod********************");
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericMethod");
object oGeneric = Activator.CreateInstance(type);
//foreach (var item in type.GetMethods())
//{
// Console.WriteLine(item.Name);
//}
MethodInfo method = type.GetMethod("Show");
var methodNew = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
object oReturn = methodNew.Invoke(oGeneric, new object[] { , "test", DateTime.Now });
}
{
Console.WriteLine("********************GenericMethod+GenericClass********************");
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericDouble`1").MakeGenericType(typeof(int));
object oObject = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("Show").MakeGenericMethod(typeof(string), typeof(DateTime));
method.Invoke(oObject, new object[] { , "teat", DateTime.Now }); }

反射破坏单例

    /// <summary>
/// 单例模式:类,能保证在整个进程中只有一个实例
/// </summary>
public sealed class Singleton
{
private static Singleton _Singleton = null;
private Singleton()
{
Console.WriteLine("Singleton被构造");
} static Singleton()
{
_Singleton = new Singleton();
} public static Singleton GetInstance()
{
return _Singleton;
}
}
                  {

                    Console.WriteLine("********************Singleton********************");
Singleton singleton1 = Singleton.GetInstance(); //new Singleton();
Singleton singleton2 = Singleton.GetInstance();
Singleton singleton3 = Singleton.GetInstance();
Singleton singleton4 = Singleton.GetInstance();
Singleton singleton5 = Singleton.GetInstance();
Console.WriteLine($"{object.ReferenceEquals(singleton1, singleton5)}"); //反射破坏单例---就是发射调用私有构造函数
Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");
Type type = assembly.GetType("Ruanmou.DB.SqlServer.Singleton");
Singleton singletonA = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonB = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonC = (Singleton)Activator.CreateInstance(type, true);
Singleton singletonD = (Singleton)Activator.CreateInstance(type, true);
Console.WriteLine($"{object.ReferenceEquals(singletonA, singletonD)}");
}

本文参考文档:

https://www.cnblogs.com/loverwangshan/p/9883243.html;

微软文档地址:

.NET Framework 中的反射:https://docs.microsoft.com/zh-cn/dotnet/framework/reflection-and-codedom/reflection;

System.Reflection Namespace:https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection?view=netframework-4.7.2;

Type Class:https://docs.microsoft.com/zh-cn/dotnet/api/system.type?view=netframework-4.7.2;

C# 反射Reflection——反射反射程序员的快乐的更多相关文章

  1. 反射反射,程序员的快乐+反射案例:打印和Excel导出

    还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 看过设计模式的童鞋都知道:反射反射,程序员的快乐!今天我们就利用反射来制作打印 ...

  2. C# 反射Reflection Assembly

    反射反射程序员的快乐 一:什么叫反射 反射:是.net framework提供的一个访问metadata的帮助类,可以获取信息并且使用 反射的优点:动态 反射的缺点:1:稍微麻烦  2:能避开编译器的 ...

  3. C# 反射 Reflection Assembly

    本章节带来的是反射,反射反射程序员的快乐. 一.什么叫反射 反射:是.net Framework提供给的一个方面metadata的帮助类,可以获取信息并且使用 反射的有点:动态 反射的缺点:1:稍微麻 ...

  4. .NET 反射(Reflection)

    这节讲一下.NET 中的一个技术:反射(Reflection). 反射是一种很重要的技术,它可以在程序运行时,动态的获取类的实例,并调用实例中的任何方法.它就像一面镜子,映射出一个类的所有细节.    ...

  5. Java---类反射(1)---类反射入门和基础

    什么是类反射 ☆什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方 ...

  6. [Java程序员面试宝典]读书笔记

    ClassLoader具备层次关系,且不止一种.不同的类装载器分布创建的同一个类的字节码数据属于完全不同的对象,没有任何关联 通过Class.forName(String className),能够动 ...

  7. 黑马程序员_Java基础:反射机制(Reflection)总结

    ------- android培训.java培训.期待与您交流! ---------- 反射在java中有非常重大的意义,它是一种动态的相关机制,可以于运行时加载.探知.使用编译期间完全未知的clas ...

  8. 黑马程序员:Java基础总结----反射

    黑马程序员:Java基础总结 反射   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...

  9. Java程序员都需要懂的「反射」

    前言 只有光头才能变强. 文本已收录至我的GitHub精选文章,欢迎Star:https://github.com/ZhongFuCheng3y/3y 今天来简单写一下Java的反射.本来没打算写反射 ...

随机推荐

  1. Springboot源码分析之事务拦截和管理

    摘要: 在springboot的自动装配事务里面,InfrastructureAdvisorAutoProxyCreator ,TransactionInterceptor,PlatformTrans ...

  2. PHP 与 MySQL 相关操作

    一.MySQL基操 •MySQL启动 注意:MySQL不能直接通过 mysql.exe 命令启动 MySQL客户端访问服务端需要寻找匹配:连接认证 连接:IP和端口确定,如果是本地都可以忽略 -h 主 ...

  3. 解决org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xyfer.dao.UserDao.findById

    在使用Spring整合MyBatis的时候遇到控制台报错:org.apache.ibatis.binding.BindingException: Invalid bound statement (no ...

  4. IDEA maven使用tomcat7插件启动报错:A child container failed during start

    使用maven的tomcat7插件启动项目时出现上面的错误:A child container failed during start, 出现这个问题的原因是导入了servlet-api包,与tomc ...

  5. 自制轮子 canvas tree

    这是树的效果 这个树拥有的功能有 1.小地图显示 2.小地图点击快速定位 3.点击加减显示根节点 4.基本的数显示 5.节点拖拽 6.点击头像跳转到相关页面 7.使用直角线和直线选择 8.画布自适应 ...

  6. 【selenium】- webdriver常见元素定位(上)

    本文由小编根据慕课网视频亲自整理,转载请注明出处和作者. 1. 元素的定位 2.By.id 打开Firefox,打开百度首页,右键点击选择“使用Firebug”查看元素. 点击红框内的按钮,将鼠标指针 ...

  7. HDU-4857-逃生-反向拓扑排序+优先队列

    HDU-4857 题意就是做一个符合条件的排序,用到拓扑序列. 我一开始wa了多发,才发现有几个样例过不了,发现1->2->3...的顺序无法保证. 后来就想用并查集强连,还是wa: 后来 ...

  8. HDU- 6437.Videos 最“大”费用流 -化区间为点

    参考和完全学习:http://www.cnblogs.com/xcantaloupe/p/9519617.html HDU-6437 题意: 有m场电影,电影分为两种,看一场电影可以得到对应的快乐值. ...

  9. 2019杭电多校6 hdu6638 Snowy Smile(二维最大矩阵和 线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6638 题意:给你一些点的权值,让找一个矩形圈住一部分点,问圈住点的最大权值和 分析:由于是稀疏图,明显要先把x, ...

  10. 牛客多校第五场 F take 期望转化成单独事件概率(模板) 树状数组

    链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 Kanade has n boxes , the i-th box has p[i] proba ...