什么是反射
IL: 也是一种面向对象语言,但是不太好阅读
metadata元数据:数据清单,描述了DLL/exe里面的各种信息
反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库 ,可以读取并使用metadata
反射的几种功能及实现
动态加载程序并创建对象
namespace Reflection.DB.MySql
{
public class MySqlHelper : IDBHelper
{
public MySqlHelper()
{
//GetType获取当前实例的 Type。
//Name获取当前成员的名称。
Console.WriteLine($"{this.GetType().Name}被构造");
}
public void Query()
{
Console.WriteLine($"{this.GetType().Name}.query");
}
}
}
#region 动态加载程序并创建对象
{
//动态加载 一个完整的dll名称不需要后缀,从exe所在的路径进行查找
Assembly assembly = Assembly.Load("Reflection.DB.MySql");
//完整路径(全路径+文件后缀)
Assembly assembly1 = Assembly.LoadFile(@"C:\Users\Lenovo\Source\Repos\Csharp高级编程\MyReflectionProject\bin\Debug\netcoreapp3.1\Reflection.DB.MySql.dll");
//当前路径 (默认在当前路径查找 Dll全名称+后缀)
Assembly assembly2 = Assembly.LoadFrom("Reflection.DB.MySql.dll");
//路径同assembly1
Assembly assembly3 = Assembly.LoadFile(@"C:\Users\Lenovo\Source\Repos\Csharp高级编程\MyReflectionProject\bin\Debug\netcoreapp3.1\Reflection.DB.MySql.dll");
foreach (var type in assembly.GetTypes())
{
Console.WriteLine(type.Name);
}
}
{
//1. 动态加载 一个完整的dll名称不需要后缀,从exe所在的路径进行查找
Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");
//2. 获取程序集中指定的类型,路径是全名称(命名空间+类名)
Type type = assembly.GetType("Reflection.DB.SqlServer.SqlServerHelper");
//3. 根据类型创建对象
object objSqlServer = Activator.CreateInstance(type);
//dynamic dSqlhelper = Activator.CreateInstance(type); //动态类型不安全
// dSqlhelper.Query();
//dSqlhelper.show(); 不安全,避开编译器的检查
//4. 类型转换
IDBHelper dBHelper = objSqlServer as IDBHelper;
//5. 调用方法
dBHelper.Query();
}
//工厂方法进行包装
{
IDBHelper dBHelper = SimpleFactory.CreateInstace();
}
#endregion
public class SimpleFactory
{
private static string IDBHelperConfig="Reflection.DB.SqlServer";
private static string DllName = "Reflection.DB.SqlServer";
private static string TypeName = "Reflection.DB.SqlServer.SqlServerHelper";
public static IDBHelper CreateInstace()
{
//1. 动态加载 一个完整的dll名称不需要后缀,从exe所在的路径进行查找
Assembly assembly = Assembly.Load(DllName);
//2. 获取程序集中指定的类型,路径是全名称(命名空间+类名)
Type type = assembly.GetType(TypeName);
//3. 根据类型创建对象
object objSqlServer = Activator.CreateInstance(type);
//dynamic dSqlhelper = Activator.CreateInstance(type); //动态类型不安全
// dSqlhelper.Query();
//dSqlhelper.show(); 不安全,避开编译器的检查
//4. 类型转换
IDBHelper dBHelper = objSqlServer as IDBHelper;
//5. 调用方法
return dBHelper;
}
}
反射破坏单例 调用私有构造函数
/// <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;
}
}
Singleton singleton = Singleton.GetInstance();
Singleton singleton1 = Singleton.GetInstance();
Singleton singleton2 = Singleton.GetInstance();
Console.WriteLine(object.ReferenceEquals(singleton, singleton1)); //返回true,表示是为单例
Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");
Type type = assembly.GetType("Reflection.DB.SqlServer.Singleton");
Singleton oSingleto = (Singleton)Activator.CreateInstance(type, true); //第二个参数为true可以访问私有的方法
Singleton oSingleto1 = (Singleton)Activator.CreateInstance(type, true);
Console.WriteLine(object.ReferenceEquals(oSingleto, oSingleto1)); //返回false
反射调用方法
Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");
Type type = assembly.GetType("Reflection.DB.SqlServer.ReflectionTest");
object oReflectionTest = Activator.CreateInstance(type, true); //创建对象
// public void Show1() 无参
MethodInfo methodShow1 = type.GetMethod("Show1");
methodShow1.Invoke(oReflectionTest, new object[] { });
// public void Show2(int id) 有参
MethodInfo methodShow2 = type.GetMethod("Show2");
methodShow2.Invoke(oReflectionTest, new object[] { 123 });
//public void Show3(int id,string name) 重载
MethodInfo methodShow3 = type.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });
methodShow3.Invoke(oReflectionTest, new object[] { 123, "zhangsan" });
// public void Show3(string name, int id) 重载
MethodInfo methodShow3_2 = type.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });
methodShow3_2.Invoke(oReflectionTest, new object[] { "wangwu", 123 });
//private void Show4(string name) 私有方法
MethodInfo methodShow4 = type.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
methodShow4.Invoke(oReflectionTest, new object[] { "wangwu" });
// public static void Show5(string name) 静态方法
MethodInfo methodShow5 = type.GetMethod("Show5");
methodShow5.Invoke(oReflectionTest, new object[] { "wangwu" });
methodShow5.Invoke(null, new object[] { "wangwu" });
ReflectionTest
namespace Reflection.DB.SqlServer
{
/// <summary>
/// 反射测试类
/// </summary>
public class ReflectionTest
{
#region Identity
/// <summary>
/// 无参数构造函数
/// </summary>
public ReflectionTest()
{
Console.WriteLine($"这里是{this.GetType()}无参数构造函数");
}
/// <summary>
/// 有参数构造函数
/// </summary>
/// <param name="name"></param>
public ReflectionTest(string name)
{
Console.WriteLine($"这里是{this.GetType()}有参数构造函数");
}
/// <summary>
/// 有参数构造函数
/// </summary>
/// <param name="id"></param>
public ReflectionTest(int id)
{
Console.WriteLine($"这里是{this.GetType()}有参数构造函数");
}
/// <summary>
/// 多参数构造函数
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public ReflectionTest(int id,string name)
{
Console.WriteLine($"这里是{this.GetType()}有参数构造函数");
}
#endregion
#region Method
/// <summary>
/// 无参数方法
/// </summary>
public void Show1()
{
Console.WriteLine($"这里是{this.GetType()}的show1");
}
/// <summary>
/// 有参数方法
/// </summary>
/// <param name="id"></param>
public void Show2(int id)
{
Console.WriteLine($"这里是{this.GetType()}的show2");
}
#region show3 重载
/// <summary>
/// 重载方法之一
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public void Show3(int id,string name)
{
Console.WriteLine($"这里是{this.GetType()}的show3");
}
/// <summary>
/// 重载方法之二
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public void Show3(string name,int id)
{
Console.WriteLine($"这里是{this.GetType()}的show3_2");
}
/// <summary>
/// 重载方法之三
/// </summary>
/// <param name="name"></param>
/// <param name="id"></param>
public void Show3( int id)
{
Console.WriteLine($"这里是{this.GetType()}的show3_3");
}
/// <summary>
/// 重载方法之四
/// </summary>
/// <param name="name"></param>
public void Show3(string name)
{
Console.WriteLine($"这里是{this.GetType()}的show3_4");
}
// 重载方法之五
public void Show3()
{
Console.WriteLine($"这里是{this.GetType()}的show3_1");
}
#endregion
/// <summary>
/// 私有方法
/// </summary>
/// <param name="name"></param>
private void Show4(string name)
{
Console.WriteLine($"这里是{this.GetType()}的Show4");
}
/// <summary>
/// 静态方法
/// </summary>
/// <param name="name"></param>
public static void Show5(string name)
{
Console.WriteLine($"这里是{typeof(ReflectionTest)}的Show5");
}
#endregion
}
}
反射获取泛型方法
//普通类有泛型方法
Assembly assembly = Assembly.Load("Reflection.DB.SqlServer");
//普通类有泛型方法
{
Type type = assembly.GetType("Reflection.DB.SqlServer.GenericMethod");
object oReflectionTest = Activator.CreateInstance(type); //创建对象
MethodInfo method = type.GetMethod("Show");
//用类型数组的元素替代当前泛型方法定义的类型参数
MethodInfo show = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
show.Invoke(oReflectionTest, new object[] { 123, "zhang", DateTime.Now });
}
//泛型类有泛型方法
{
Type type = assembly.GetType("Reflection.DB.SqlServer.GenericClass`3"); //`3 表示泛型个数
//指定创建对象需要的泛型参数
Type GenericType = type.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
//创建对象
object oReflectionTest = Activator.CreateInstance(GenericType);
//因为方法的泛型参数在获取类型时已经获取,所以不需要再指定
MethodInfo method = GenericType.GetMethod("Show");
//用类型数组的元素替代当前泛型方法定义的类型参数
method.Invoke(oReflectionTest, new object[] { 123, "zhang", DateTime.Now });
}
//泛型类有泛型方法,并且方法中有使用到类所定义的泛型类型
{
Type type = assembly.GetType("Reflection.DB.SqlServer.GenericDouble`1"); //`1 表示泛型个数
//指定创建对象需要的泛型参数
Type GenericType = type.MakeGenericType(new Type[] { typeof(bool)});
//创建对象
object oReflectionTest = Activator.CreateInstance(GenericType);
MethodInfo method = GenericType.GetMethod("Show");
//获取方法的泛型参数类型
MethodInfo show = method.MakeGenericMethod(new Type[] { typeof(string), typeof(DateTime) });
show.Invoke(oReflectionTest, new object[] { true, "zhang", DateTime.Now });
}
namespace Reflection.DB.SqlServer
{
/// <summary>
/// 泛型类有泛型方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="W"></typeparam>
/// <typeparam name="X"></typeparam>
public class GenericClass<T, W, X>
{
public void Show(T t,W w,X x)
{
Console.WriteLine($"t.type={t.GetType().Name},w.type={w.GetType().Name},x.type{x.GetType().Name}");
}
}
/// <summary>
/// 普通类有泛型方法
/// </summary>
public class GenericMethod
{
public void Show<T, W, X>(T t, W w, X x)
{
Console.WriteLine($"t.type={t.GetType().Name},w.type={w.GetType().Name},x.type{x.GetType().Name}");
}
}
/// <summary>
/// 泛型类有泛型方法,并且方法中有使用到类所定义的泛型类型
/// </summary>
/// <typeparam name="T"></typeparam>
public class GenericDouble<T>
{
public void Show<W, X>(T t, W w, X x)
{
Console.WriteLine($"t.type={t.GetType().Name},w.type={w.GetType().Name},x.type{x.GetType().Name}");
}
}
}
反射获取属性与字段
//反射获取属性与字段
{
People people = new People
{
Id = 123,
Name = "zH",
Description = "dy"
};
Console.WriteLine($"id={people.Id},name={people.Name},description={people.Description}");
Type type = typeof(People);
object oPeople=Activator.CreateInstance(type);
//设置属性值
foreach (PropertyInfo prop in type.GetProperties())
{
if (prop.Name.Equals("Id"))
{
prop.SetValue(oPeople, 456);
}
else if (prop.Name.Equals("Name"))
{
prop.SetValue(oPeople, "hu");
}
Console.WriteLine(prop.GetValue(oPeople));
}
//设置字段
foreach (FieldInfo field in type.GetFields())
{
if (field.Name.Equals("Description"))
{
field.SetValue(oPeople, "描述信息");
}
}
//获取属性
foreach (PropertyInfo prop in type.GetProperties())
{
Console.WriteLine($"oPeople.{prop.Name}={prop.GetValue(oPeople)}");
}
//获取字段
foreach (FieldInfo field in type.GetFields())
{
Console.WriteLine($"oPeople.{field.Name}={field.GetValue(oPeople)}");
}
}
namespace Reflection.Model
{
public class People
{
public People()
{
Console.WriteLine($"{this.GetType().FullName}被创建");
}
public int Id { get; set; }
public string Name { get; set; }
public string Description;
}
}