泛型:读取DLL文件描述信息的一个类库
exe/dll(主要区别就是exe文件入口)–metadata(元数据:描述exe/dll文件的一个数据清单)–反射(Reflection)用来操作获取元数据(metadata)
【1】更新程序时(更新自己的DLL)
【2】使用别人的DLL文件(这种可以读取别人的私有的类型东西)
1. 反射时什么?它就是一个操作metadata数据的一个类库(可以把反射当成一个小工具,用来读取或者操作元数据的)类,方法,特性,属性字段。(为什么要通过反射间接的去操作,1–因为我们需要动态2–读取私有的对象)
2. 使用场合?哪些地方使用到了:asp.net MVC–ORM–IOC–AOP 几乎所有的框架都会使用反射
反射—反射工具—操作metadate【dll中的】(元数据)的工具
通过反射加载DLL文件,相当于把路径找出来
代码示例
using Reflection.DB.Interface;
using Reflection.DB.SQLServer;
using System;
using System.Reflection;
namespace MyReflection
{
class Program
{
static void Main(string[] args)
{
try
{
#region
Console.WriteLine("-------------------------------Reflection-------------------------------");
Console.WriteLine("----加载方式一:dll文件名【需要引用dll】-----");
Assembly assembly = Assembly.Load("Reflection.DB.SQLServer");//加载方式一:dll文件名
foreach (var type in assembly.GetTypes())
{
Console.WriteLine("类名{0}:", type.Name);
foreach (var method in type.GetMethods())
{
Console.WriteLine("方法名{0}:", method.Name);
}
}
Console.WriteLine("----加载方式二:完整路径【不需要引用dll】-----");
Assembly assembly2 = Assembly.LoadFile(@"F:\01博客代码\02MyReflection\MyReflection\Reflection.DB.Interface\bin\Debug\Reflection.DB.Interface.dll");
foreach (var type in assembly2.GetTypes())
{
Console.WriteLine("类{0}:", type.Name);
foreach (var method2 in type.GetMethods())
{
Console.WriteLine("方法{0}:", method2.Name);
}
}
Console.WriteLine("----加载方式三:完全限定名【需要引用dll】-----");
Assembly assembly3 = Assembly.LoadFrom("Reflection.DB.MySql.dll");
foreach (var type3 in assembly3.GetTypes())//找到所有类型
{
Console.WriteLine("类{0}:", type3.Name);
foreach (var method3 in type3.GetMethods())//找到类型下的所有方法
{
Console.WriteLine("方法{0}:", method3.Name);
}
}
#endregion
#region 使用反射创建对象 反射工具 进行操作DLL的
Console.WriteLine("-------------------------------使用反射创建对象-------------------------------");
Assembly assembly4 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type1 = assembly4.GetType("Reflection.DB.SQLServer.SQLServerHelper");//【2】获取类型(要完整类型名称)
object oDbHelper = Activator.CreateInstance(type1);//创建对象【创建了对象,在此处,进行调用SQLServerHelper类中的构造函数】
IDBHelper dBHelper = oDbHelper as IDBHelper;//类型转换 (as转换不报错,类型不对就返回null)
//IDBHelper dBHelper2 = (IDBHelper)oDbHelper;//转换不成功就会报错,不建议使用这种方式
dBHelper.Query();
#endregion
#region 反射创建对象(带参数的构造函数)
Console.WriteLine("----------cotr&Parameter---------------");
Assembly assembly5 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type2 = assembly5.GetType("Reflection.DB.SQLServer.ReflectionTest");//【2】获取类型(要完整类型名称)
//获取到这个类型下面所有构造方法
foreach (ConstructorInfo ctor in type2.GetConstructors())//获取到所有的构造 方法
{
Console.WriteLine(ctor.Name);
foreach (var parameter in ctor.GetParameters())//获取到构造方法的所有参数类型
{
Console.WriteLine(parameter.ParameterType);//显示类型名称
}
}
Console.WriteLine("----------创建对象---------------");
object oCotr = Activator.CreateInstance(type2);//无参构造函数
object oCotr1 = Activator.CreateInstance(type2, new object[] { "编程" });
object oCotr2 = Activator.CreateInstance(type2, new object[] { 123 });//进行自动匹配
//相当于下面的写法
ReflectionTest reflectionTest = new ReflectionTest("测试编程");
#endregion
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
#region 使用反射创建对象 (私有构造函数)
//这个功能 还用在我们的单例模式里面(一个对象只能创建一次),这个也叫反射破坏单例
Console.WriteLine("----------ctor&&Private---------------");
Assembly assembly6 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type4 = assembly6.GetType("Reflection.DB.SQLServer.PrivateCtor");//【2】获取类型(要完整类型名称)
object oPrivate = Activator.CreateInstance(type4, true);
#endregion
#region 使用反射创建泛型类
Console.WriteLine("----------Generic&&Class---------------");
Assembly assembly7 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//反射的作用就是用来读取DLL
Type type5 = assembly7.GetType("Reflection.DB.SQLServer.GenericClass`3");//【2】获取类型(要完整类型名称)
Type makeType = type5.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(double) });
object oGeneric = Activator.CreateInstance(makeType);
#endregion
#region 通过反射调用方法
Console.WriteLine("----------Method&&&Refection---------------");
Assembly assembly8 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type6 = assembly8.GetType("Reflection.DB.SQLServer.ReflectionTest");//【2】获取类型(要完整类型名称)
object oReflection = Activator.CreateInstance(type6);//创建对象【创建了对象,在此处,进行调用SQLServerHelper类中的构造函数】
foreach (var method in type6.GetMethods())//所有的方法类型
{
Console.WriteLine(method.Name);
foreach (var parameter in method.GetParameters())
{
Console.WriteLine(parameter.Name + "是:" + parameter.ParameterType);
}
}
//无参数方法调用
{
MethodInfo methodInfo = type6.GetMethod("Test1", new Type[] { });
methodInfo.Invoke(oReflection, null);//调用方法
}
//有参数的方法调用
{
MethodInfo methodInfo = type6.GetMethod("Test3", new Type[] { typeof(int), typeof(string) });
methodInfo.Invoke(oReflection, new object[] { 123456, "测试" });//调用方法
}
//静态方法的调用
{
MethodInfo methodInfo = type6.GetMethod("Test2");
methodInfo.Invoke(oReflection, null);//调用方法
}
#endregion
#region MyRegion
//在显示之前做一点其他事情AOP
Console.WriteLine("----------反射MVC和AOP---------------");
//在显示之后做一点事情AOP
//DLl文件名称+类型名称+方法名称(就可以拿到我们的方法)
//https://localhost:44352/Home/Index //主机名称,控制器,类型 路由 其本质是反色
//反射 在MVC中 一些缺点
//AOP 什么是AOP 是面向切面编程 是OOP对象技术的一种补充
#endregion
#region 通过反射调用私有方法
Console.WriteLine("-----------------private&Reflection-------------------");
Assembly assembly9 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type7 = assembly9.GetType("Reflection.DB.SQLServer.ReflectionTest");//【2】获取类型(要完整类型名称)
object oReflection1 = Activator.CreateInstance(type7);//创建对象【创建了对象,在此处,进行调用SQLServerHelper类中的构造函数】
MethodInfo methodInfo1 = type7.GetMethod("Test4", BindingFlags.Instance | BindingFlags.NonPublic);
methodInfo1.Invoke(oReflection1, new object[] { "编程测试" });
#endregion
#region 通过反射调用泛型方法[普通类方法中的调用]
Console.WriteLine("-----------------GenericMethod-------------------");
Assembly assembly10 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type8 = assembly10.GetType("Reflection.DB.SQLServer.GenericMethod");//【2】获取类型(要完整类型名称)
object oReflection2 = Activator.CreateInstance(type8);//实例化类型
MethodInfo methodInfo2 = type8.GetMethod("Test");//找到调用的方法
var methodGeneric = methodInfo2.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定参数与参数类型
methodGeneric.Invoke(oReflection2, new object[] { 1, "编程", DateTime.Now });
#endregion
#region 通过反射调用泛型方法[泛型类中,泛型方法的调用]
Console.WriteLine("-----------------GenericMethod-------------------");
Assembly assembly11 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type9 = assembly11.GetType("Reflection.DB.SQLServer.GenericClass`3");//【2】获取类型(要完整类型名称)【`3】表示桑额参数
Type typeNew = type9.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) }); //确定泛型方法的参数类型
object oReflection3 = Activator.CreateInstance(typeNew);//实例化类型
MethodInfo methodInfo3 = typeNew.GetMethod("Test");//找到调用的方法
MethodInfo methodInfoNew3 = methodInfo3.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定参数与参数类型
methodInfoNew3.Invoke(oReflection3, new object[] { 1, "编程", DateTime.Now });
Console.WriteLine("-----------------链式编程GenericMethod-------------------");
Assembly assembly12 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
Type type10 = assembly12.GetType("Reflection.DB.SQLServer.GenericClass`3").MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
//Type typeNew1 = type10.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
object oReflection4 = Activator.CreateInstance(typeNew);
MethodInfo methodInfo4 = type10.GetMethod("Test").MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
//MethodInfo methodInfoNew4 = methodInfo4.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定参数与参数类型
methodInfo4.Invoke(oReflection4, new object[] { 2, "链式编程", DateTime.Now });
#endregion
Console.WriteLine("-----------------通过反射操作字段和属性等成员-----------");
Student student = new Student()
{
id = 1,
StudentName = "ceshi名称",
StudentAddress = "ceshi地址"
};
Assembly assembly00 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//获取dll信息
Type type00 = assembly00.GetType("Reflection.DB.SQLServer.Student");//找到需要操作的对象类型
object oStudent = Activator.CreateInstance(type00);//创建对象
foreach (var prop in type00.GetProperties())
{
Console.WriteLine($"{prop.PropertyType}+{prop.Name}={prop.GetValue(student)}");
Console.WriteLine("----------------------------------------------");
if (prop.Name.Equals("id"))
{
prop.SetValue(student, 2);
}
if (prop.Name.Equals("StudentName"))
{
prop.SetValue(student, "北京");
}
if (prop.Name.Equals("StudentAddress"))
{
prop.SetValue(student, "中国北京");
}
Console.WriteLine($"{prop.PropertyType}+{prop.Name}={prop.GetValue(student)}");
}
//方式二
//MethodInfo info 成员信息包含-字段 属性 方法
PropertyInfo[] propertyInfos = type00.GetProperties();//查找所有的属性
PropertyInfo propertyInfo = type00.GetProperty("id");
Console.ReadKey();
}
}
}