博客
关于我
C# 反射
阅读量:423 次
发布时间:2019-03-06

本文共 5159 字,大约阅读时间需要 17 分钟。

C# 反射操作实用指南

反射(Reflection)是C#中一个强大的工具,允许程序在运行时动态获取和修改类的元数据。以下是通过反射实现的一些常见操作示例,供开发者参考。


一、获取程序集与动态加载

动态加载程序集是反射的基础操作,常用于处理不明事先的动态链接库(DLL)。

// 动态加载程序集Assembly assembly = Assembly.Load("Ruanmou.DB.MySql");// 从特定路径加载完整文件Assembly assembly1 = Assembly.LoadFile(@"D:\ruanmou\online12\20181212Advanced12Course2Reflection\MyReflection\MyReflection\bin\Debug\Ruanmou.DB.MySql.dll");// 从当前路径加载文件Assembly assembly2 = Assembly.LoadFrom("Ruanmou.DB.MySql.dll");// 指定路径加载文件Assembly assembly3 = Assembly.LoadFrom(@"D:\ruanmou\online12\20181212Advanced12Course2Reflection\MyReflection\MyReflection\bin\Debug\Ruanmou.DB.MySql.dll");

二、获取类型、创建对象与调用方法

通过反射可以获取类的类型信息,创建对象并调用方法。

// 获取类型信息Type type = assembly.GetType("Ruanmou.DB.MySql.MySqlHelper");// 创建对象object oDBHelper = Activator.CreateInstance(type);// 类型转换IDBHelper iDBHelper = oDBHelper as IDBHelper;// 调用方法iDBHelper.Query();

三、获取不同构造函数并创建实例

通过反射可以遍历类的构造函数,创建不同参数化的实例。

// 遍历构造函数foreach (ConstructorInfo ctor in type.GetConstructors()){    Console.WriteLine(ctor.Name);    foreach (var parameter in ctor.GetParameters())    {        Console.WriteLine(parameter.ParameterType);    }}// 创建不同参数的实例object oTest1 = Activator.CreateInstance(type);object oTest2 = Activator.CreateInstance(type, new object[] { 123 });object oTest3 = Activator.CreateInstance(type, new object[] { "陌殇" });

四、创建单例实例

反射可以用来破坏单例模式,通过调用私有构造函数创建多个实例。

// 加载类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);Console.WriteLine($"{object.ReferenceEquals(singletonA, singletonD)}");

五、创建泛型类实例

通过反射可以创建泛型类的实例,包括指定参数化类型。

// 加载类Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericClass`3");// 创建泛型实例Type typeMake = type.MakeGenericType(new Type[] { typeof(string), typeof(int), typeof(DateTime) });object oGeneric = Activator.CreateInstance(typeMake);

六、调用重载方法

通过反射可以获取方法信息并调用重载版本。

// 加载类Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");object oTest = Activator.CreateInstance(type);// 调用不同重载版本MethodInfo method = type.GetMethod("Show1");method.Invoke(oTest, null);MethodInfo method2 = type.GetMethod("Show2");method2.Invoke(oTest, new object[] { 123 });// 进一步演示泛型方法调用MethodInfo method3 = type.GetMethod("Show3");method3.Invoke(oTest, new object[] { 123, "一生为你" });

七、调用私有方法

通过设置正确的绑定属性,可以调用类的私有方法。

// 加载类Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");Type type = assembly.GetType("Ruanmou.DB.SqlServer.ReflectionTest");object oTest = Activator.CreateInstance(type);// 调用私有方法var method = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);method.Invoke(oTest, new object[] { "我是老王" });

八、调用泛型方法

通过反射可以调用泛型方法,并指定参数化类型。

// 加载类Assembly assembly = Assembly.Load("Ruanmou.DB.SqlServer");Type type = assembly.GetType("Ruanmou.DB.SqlServer.GenericMethod");object oGeneric = Activator.CreateInstance(type);// 调用泛型方法MethodInfo method = type.GetMethod("Show");var methodNew = method.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });object oReturn = methodNew.Invoke(oGeneric, new object[] { 123, "董小姐", DateTime.Now });

九、调用泛型类的泛型方法

通过反射可以调用泛型类的泛型方法,并传递具体类型参数。

// 加载类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");method.MakeGenericMethod(typeof(string), typeof(DateTime));method.Invoke(oObject, new object[] { 345, "感谢有梦", DateTime.Now });

十、反射与ORM

通过反射可以操作对象的属性和字段,常用于ORM(对象关系映射)中。

// 加载类Type type = typeof(People);object oPeople = Activator.CreateInstance(type);// 遍历属性foreach (var prop in type.GetProperties()){    Console.WriteLine($"{type.Name}.{prop.Name} = {prop.GetValue(oPeople)}");    if (prop.Name == "Id")    {        prop.SetValue(oPeople, 234);    }    else if (prop.Name == "Name")    {        prop.SetValue(oPeople, "饿了么");    }    Console.WriteLine($"{type.Name}.{prop.Name} = {prop.GetValue(oPeople)}");}// 遍历字段foreach (var field in type.GetFields()){    Console.WriteLine($"{type.Name}.{field.Name} = {field.GetValue(oPeople)}");    if (field.Name == "Description")    {        field.SetValue(oPeople, "并不是外卖,也不是真的饿了");    }    Console.WriteLine($"{type.Name}.{field.Name} = {field.GetValue(oPeople)}");}

十一、反射与DTO(数据传输对象)

通过反射可以将一个对象的属性和字段映射到另一个 DTO 类中。

// 加载类Type typePeople = typeof(People);Type typePeopleDTO = typeof(PeopleDTO);object peopleDTO = Activator.CreateInstance(typePeopleDTO);// 遍历 DTO 的属性foreach (var prop in typePeopleDTO.GetProperties()){    object value = typePeople.GetProperty(prop.Name).GetValue(people);    prop.SetValue(peopleDTO, value);}// 遍历 DTO 的字段foreach (var field in typePeopleDTO.GetFields()){    object value = typePeople.GetField(field.Name).GetValue(people);    field.SetValue(peopleDTO, value);}

以上示例展示了反射在C#中的常见应用场景,包括动态加载、类型操作、单例管理、泛型处理、方法调用等。通过合理使用反射,可以显著提升程序的灵活性和可维护性。

转载地址:http://dviuz.baihongyu.com/

你可能感兴趣的文章
Objective-C实现armstrong numbers阿姆斯壮数算法(附完整源码)
查看>>
Objective-C实现atoi函数功能(附完整源码)
查看>>
Objective-C实现base64加密和base64解密算法(附完整源码)
查看>>
Objective-C实现base85 编码算法(附完整源码)
查看>>
Objective-C实现basic graphs基本图算法(附完整源码)
查看>>
Objective-C实现BCC校验计算(附完整源码)
查看>>
Objective-C实现bead sort珠排序算法(附完整源码)
查看>>
Objective-C实现BeadSort珠排序算法(附完整源码)
查看>>
Objective-C实现bellman ford贝尔曼福特算法(附完整源码)
查看>>
Objective-C实现bellman-ford贝尔曼-福特算法(附完整源码)
查看>>
Objective-C实现bellman-ford贝尔曼-福特算法(附完整源码)
查看>>
Objective-C实现BellmanFord贝尔曼-福特算法(附完整源码)
查看>>
Objective-C实现BF算法 (附完整源码)
查看>>
Objective-C实现binary exponentiation二进制幂运算算法(附完整源码)
查看>>
Objective-C实现binary tree traversal二叉树遍历算法(附完整源码)
查看>>
Objective-C实现binomial coefficient二项式系数算法(附完整源码)
查看>>
Objective-C实现BitMap算法(附完整源码)
查看>>
Objective-C实现bitonic sort双调排序算法(附完整源码)
查看>>
Objective-C实现bogo sort排序算法(附完整源码)
查看>>
Objective-C实现BP误差逆传播算法(附完整源码)
查看>>