学习C#反射(Reflection)
反射提供描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。 如果代码中使用了特性(Attribute),可以利用反射来访问它们。本文主要介绍C# 反射(Reflection)。
1、C# 反射(Reflection)使用场景
反射在以下情况下很有用:
1)需要访问程序元数据中的特性时。
2)检查和实例化程序集中的类型。
3)在运行时构建新类型。 使用 System.Reflection.Emit
中的类。
4)执行后期绑定,访问在运行时创建的类型上的方法。可以动态调用执行方法。
5)还可以使用反射,动态加载程序集创建对象调用方法,一般CS程序中插件一般可以这样实现。
2、C# 反射(Reflection)的使用
下面通过一个简单的示例,了解一下最简单的反射,使用方法 GetType()(被 Object
基类的所有类型继承)以获取变量类型:
例如,
//使用GetType获取类型信息:
int i = 33;
Type type = i.GetType();
Console.WriteLine(type);
注意:反射一般需要引用using System;
和 using System.Reflection;
这两个命名空间。
使用反射获取已加载的程序集的完整名称:
例如,
//使用反射获取程序集的信息:
Assembly info = typeof(int).Assembly;
Console.WriteLine(info);
//mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
注意:C# 关键字 protected
和 internal
在中间语言 (IL) 中没有任何意义,且不会用于反射 API 中。 在 IL 中对应的术语为“系列”和“程序集”。 若要标识 internal
使用反射的方法,请使用 IsAssembly 属性。 若要标识 protected internal 方法,请使用 IsFamilyOrAssembly。
3、C# 反射使用实例
1)使用反映将一个对象的同名属性赋值给另一个对象
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{public class VisitorInfo{public string openid { get; set; }public string wechatnick { get; set; }public string headurl { get; set; }public string mobile { get; set; }public string encryptedData { get; set; }public string iv { get; set; }public string session_key { get; set; }}public class MyObj{public string openid { get; set; }public string wechatnick { get; set; }public string headurl { get; set; }public string mobile { get; set; }public string encryptedData { get; set; }public string iv { get; set; }public string session_key { get; set; }}class Program{//为了适应更多情况,可以考虑用泛型改写public static VisitorInfo ToPageInfo(object model){VisitorInfo v = new VisitorInfo();PropertyInfo property = null;foreach (var item in typeof(VisitorInfo).GetProperties()){property = model.GetType().GetProperty(item.Name);if (property != null){item.SetValue(v, property.GetValue(model));}}return v;}static void Main(string[] args){MyObj myObj = new MyObj(){openid = "cjavapy",wechatnick = "liangliang",headurl = "https://www.cjavapy.com",mobile = "5201314",encryptedData = "",iv = "",session_key = ""};var v = ToPageInfo(myObj);Console.WriteLine(v.openid);}}
}
2)利用反映将DataTable转换成实现体对象
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace ConsoleApplication
{public class VisitorInfo{public string openid { get; set; }public string wechatnick { get; set; }public string headurl { get; set; }public string mobile { get; set; }public string encryptedData { get; set; }public string iv { get; set; }public string session_key { get; set; }}// <summary>/// 将datatable装入指定类型的集合/// </summary>/// <typeparam name="T"></typeparam>public class MyList<T>:List<T>{public MyList(DataTable dt){System.Type tt = typeof(T);//获取指定名称的类型object ff = Activator.CreateInstance(tt, null);//创建指定类型实例PropertyInfo[] fields = ff.GetType().GetProperties();//获取指定对象的所有公共属性foreach (DataRow dr in dt.Rows){object obj = Activator.CreateInstance(tt, null);foreach (DataColumn dc in dt.Columns){foreach (PropertyInfo t in fields){if (dc.ColumnName == t.Name){t.SetValue(obj, dr[dc.ColumnName], null);//给对象赋值continue;}}}this.Add((T)obj);//将对象填充到list集合}}}class Program{static void Main(string[] args){/*MyObj myObj = new MyObj(){openid = "cjavapy",wechatnick = "liangliang",headurl = "https://www.cjavapy.com",mobile = "5201314",encryptedData = "",iv = "",session_key = ""};*///从数据库中查询获取dtDataTable dt=null;var myList = new MyList<VisitorInfo>(dt);}}
}
4、使用反射获取标签(Attribute)
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{/* 特性说明特性本质是一个继承和使用了系统基类的"类",用以将元数据或声明信息与代码(程序集、类型、方法、属性等)相关联。特性与程序实体关联后,即可在运行时使用名为“反射”的技术查询特性。官方介绍的很详细,我们就一起来了解一下它的用法。特性具有以下属性:1.特性可向程序中添加元数据。元数据是有关在程序中定义的类型的信息。所有的.NET 程序集都包含指定的一组元数据,这些元数据描述在程序集中定义的类型和类型成员。可以添加自定义特性,以指定所需的任何附加信息。2.可以将一个或多个特性应用到整个程序集、模块或较小的程序元素(如类和属性)。3.特性可以与方法和属性相同的方式接受参数。4.程序可以使用反射检查自己的元数据或其他程序内的元数据。*/#region 声明一个 作用于成员方法 的特性//1.第一步 继承自定义属性的基类 Attribute//2.第二步 指定 我们自定义特性类 的一些属性,用系系统特性指定// AttributeTargets:指定为程序中的何种成员设置属性 可写多个 例: AttributeTargets.Class|AttributeTargets.Method// AllowMultiple:如果允许为一个实例多次指定该特性,则为 true;否则为 false。默认为 false。// Inherited:如果该属性可由派生类和重写成员继承,则为 true,否则为 false。默认为 true。[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]public class MethodAttribute : Attribute{/// <summary>/// 方法名称/// </summary>public string MethodName { set; get; }/// <summary>/// 方法描述/// </summary>public string MethodDesc { set; get; }/// <summary>/// 方法描述特性/// </summary>/// <param name="methodName">方法名称</param>/// <param name="methodDescription">方法描述</param>public MethodAttribute(string methodName, string methodDescription){MethodName = methodName;MethodDesc = methodDescription;}}#endregion#region 声明一个 作用于类 的特性[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]//第一步public class ClassAttribute : Attribute//第二步{string ClassName { set; get; }string ClassDesc { set; get; }public ClassAttribute(string className, string classDesc){ClassName = className;ClassDesc = classDesc;}//重写当前特性的ToString()方法public override string ToString(){return string.Format(@"当前类特性名:[ClassAttribute]
特性成员1:ClassName-->值:{0},
特性成员2:ClassDesc-->值:{1}", ClassName, ClassDesc);}}#endregion[ClassAttribute("TestClass", "测试反射及特性")]public class VisitorInfo{public string openid { get; set; }public string wechatnick { get; set; }[MethodAttribute("Demo1", "测试特性1")]public string GetHeadurl(){return "cjavapy";}public string mobile { get; set; }[MethodAttribute("Demo2", "测试特性2")]public string EncryptedData(){return "cjavapy";}public string iv { get; set; }public string session_key { get; set; }}class Program{static void Main(string[] args){//得到当前方法上的特性类 信息MethodAttribute methodAttribute = (MethodAttribute)Attribute.GetCustomAttribute(typeof(VisitorInfo).GetMethod("GetHeadurl"), typeof(MethodAttribute));if (methodAttribute != null){Console.WriteLine("输出当前方法特性信息:");Console.WriteLine("①当前调用方法名称: [" + methodAttribute.MethodName + "]");Console.WriteLine("②方法描述: [" + methodAttribute.MethodDesc + "]");}else{Console.WriteLine("当前传入的方法没有反射信息!");}Attribute attribute = Attribute.GetCustomAttribute(typeof(VisitorInfo), typeof(Attribute));if (attribute != null){Console.WriteLine(attribute.ToString());}}}
}
相关文章:
学习C#反射(Reflection)
反射提供描述程序集、模块和类型的对象(Type 类型)。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用其方法或访问器字段和属性。 如果代码中使用了特性(Attribute)…...
Spring Boot的核心组件和工作原理
引言 Spring Boot是一个快速构建应用程序的框架,通过自动化配置和约定优于配置的原则,可以快速地创建可独立运行的、生产级别的Spring应用程序。Spring Boot的核心组件是自动配置、起步依赖和嵌入式Web服务器。 在本文中,我们将深入了解Spr…...

【指针的深刻理解】
如何看待下面代码中的a变量? #include<stdio.h> int main() {int a 0;//同样的一个a,在不同的表达式中,名称是一样的,但是含义是完全不同的!a 10;//使用的是a的空间:左值int b a; //使用的是a的内容&#x…...

lintcode-图的拓扑排序(java)
拓扑排序 拓扑排序-lintcode原题题目介绍解题思路代码演示解题方法二 (参考,不用掌握)前置知识 图的拓扑序和深度优先遍历和广度优先遍历 拓扑排序-lintcode原题 127.拓扑排序-原题链接,可以点进去测试 题目介绍 描述 给定一个有向图,图节点的拓扑排序定义如下: 对…...

【状态估计】基于随机方法优化PMU优化配置(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Rinne Loves Graph
Rinne Loves Graph (nowcoder.com) 链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 Island 发生了一场暴乱!现在 Rinne 要和 Setsuna 立马到地上世界去。 众所周知:Island 是有一些奇怪的城镇和道路构成的…...

第15章:索引的数据结构
一、为什么使用索引 1.索引是存储引擎用于快速找到记录的一种数据结构。相当于一本书的目录。在进行数据查找时,首先查看查询条件是否命中某条索引,符合则通过索引查找相关数据。如果不符合则需要全表扫描,一条一条查找记录,直到…...

机械师曙光16电脑开机自动蓝屏怎么解决?
机械师曙光16电脑开机自动蓝屏怎么解决?有的用户在使用机械师曙光16电脑的时候,遇到了一些系统问题,导致自己无法正常的开机使用电脑。因为电脑总会变成蓝屏,无法进行任何操作。那么这个情况怎么去进行问题的解决呢?来…...

机器学习_Lasso回归_ElasticNet回归_PolynomialFeatures算法介绍_02---人工智能工作笔记0037
Lasso回归用的是L1正则化可以看到,这里的alpha就是这里的alpha对吧,就是 L1的权重 然后对于ElasticNet回归来说,这里的alpha可以看到是L1权重的超参数对吧,然后这里的p,表示的是 L2正则里面的(1-p)这里 这里要提一下: L1和L2为什么能防止过拟合,它们有什么区别?通过添加…...

第五篇:强化学习基础之马尔科夫决策过程
你好,我是zhenguo(郭震) 今天总结强化学习第五篇:马尔科夫决策过程 基础 马尔科夫决策过程(MDP)是强化学习的基础之一。下面统一称为:MDP MDP提供了描述序贯决策问题的数学框架。 它将决策问题建模为: 状态…...
Oracle面试题
1. 什么是存储过程,使用存储过程的好处? 存储过程(Stored Procedure )是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数&#…...

用Vue写教务系统学生管理
文章目录 一.首先创建新的Demo二.在APP里面绑定DemoStudent三.源码附上四.效果图(新增记录还未实现) 一.首先创建新的Demo 二.在APP里面绑定DemoStudent <template><img alt"Vue logo" src"./assets/logo.png"><!--…...

专门用于管理企业与自己客户之间所有信息的客户管理系统
一、开源项目简介 关于 NXCRM NXCRM 是一套基于 Laravel 的 CRM 应用程序。它包含了一个管理中心,可以管理用户、客户、产品、订单、商机,合同,收款,附件,联系人,跟进动态,发票,业…...

(转载)基于多层编码遗传算法的车间调度算法(matlab实现)
以下内容大部分来源于《MATLAB智能算法30个案例分析》,仅为学习交流所用。 1 理论基础 遗传算法具有较强的问题求解能力,能够解决非线性优化问题。遗传算法中的每个染色体表示问题中的一个潜在最优解,对于简单的问题来说,染色体…...

Redis的常用数据结构之哈希类型
首先这里说的哈希类型针对的是redis中的value的k-v结构 常见的操作命令 hset设置值 hsetnx命令,不存在可以设置,存在设置不成功 hget取值,这里与字符串类型不同是要精确到filed。前面的判断也是基于field来实现的 要是field没有就返回null h…...

计算机组成原理-存储系统-缓存存储器(Cache)
目录 一、Cache基本概念 1.2性能分析 二、 Cache和主存的映射发生 2.1全相连映射编辑 2.2直接映射编辑 2.3组相连映射 三、Cachae的替换算法 3.1 随机算法(RADN) 3.2 先进先出算法(FIFO) 3.3 近期最少使用(LRU) 3.4 最近不经常使用(LFU) 四、写策略 4…...
打开c语言生成exe文件,出现闪退的解决方法
为什么打开c语言生成的exe文件,立马闪退。 起初个别问的时候,我只是简单的说明程序运行完了,就自动关了, 首先,生成的exe文件本质是控制台程序,这些都是依赖于windows的控制台窗口,程序执行完…...

算法基础学习笔记——⑩DFS与BFS\树与图
✨博主:命运之光 ✨专栏:算法基础学习 目录 DFS与BFS\树与图 ✨DFS ✨BFS 🍓宽搜流程图如下: 🍓宽搜流程: 🍓广搜模板 ✨树与图 🍓树是特殊的图(连通无环的图&am…...

chatgpt赋能python:Python中可迭代对象的介绍
Python中可迭代对象的介绍 Python是一种高级编程语言,它具有简单易学、可读性强、功能强大等特点,成为了数据科学、机器学习、Web开发等领域的热门选择。Python中有很多重要的概念和功能,其中之一就是支持可迭代对象的概念。 在Python中&am…...

报表控件FastReport使用指南——如何打开WebP格式的图片
FastReport 是功能齐全的报表控件,可以帮助开发者可以快速并高效地为.NET,VCL,COM,ActiveX应用程序添加报表支持,由于其独特的编程原则,现在已经成为了Delphi平台最优秀的报表控件,支持将编程开…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...