一、什么是反射
反射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. from 表单用 GET 方法进行 URL 传值时后台无法获取问题

    问题描述 <a href="${pageContext.request.contextPath}/client?method=add">点我</a> < ...

  2. RocketMQ 4.3.2 standalone Installation and Configuration

    1 Download RockeMQ Package: You need to download it and put it to the OS Image. wget http://apache.c ...

  3. C++ 线程安全的单例模式总结

    什么是线程安全? 在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况. 如何保证线程安全? 给共享的资源加把锁,保证每 ...

  4. egret之好友列表(滑动列表)

    本文采用List+Scroller实现列表滑动功能 首先新建两个皮肤,一个用做好友界面的显示,一个用作单个好友的显示,新建皮肤如下: 皮肤一取名为:wxMainSkin,添加如下控件 皮肤一取名为:w ...

  5. 变量声明关键字var ,let,const

    今天带大家了解的是比较有趣的几个变量声明关键字var,let,const. 我们在最初接触JS的时候,变量是我们重要的一个组成部分,在使用时规定必须要先进行声明,否则网页将会报错: console.l ...

  6. net core WebApi——尝试企业微信内部应用

    目录 前言 企业微信 开始 测试 小结 @ 前言 这几天忙活着别的东西,耽误了很长时间,从文件操作完了之后就在考虑着下一步鼓捣点儿啥,因为最开始的业务开发就是企业微信相关的,这刚好来做个内部应用的小例 ...

  7. 页面单击按钮弹出modaldialog然后调用ajax处理程序获取数据,给父级页面控件赋值

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="RefTopicList.asp ...

  8. node.js常用的全局成员和对象

    一般可以直接调用的对象,我们称之为全局对象: 一下对象都加了console.log(),以在运行环境中的显示效果为标准 //包含文件名称的全路径:    console.log(_filename); ...

  9. 上海学生事务中心&新华路派出所的位置

    上海学生事务中心: 地址:冠生园路401号    工作时间:9:00-17:00    电话:021-64829191 新华路派出所: 地址:新华路590弄21号    工作时间:周一至周六 9:00 ...

  10. Badboy - 导出脚本,用于JMeter并发测试

    参考: http://leafwf.blog.51cto.com/872759/1141011 http://www.51testing.com/html/00/130600-1367743.html ...