NET基础篇——反射的奥妙
反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等程序集内部的信息。使用反射可以看到一个程序集内部的接口、类、方法、字段、属性、特性等等信息。在System.Reflection命名空间内包含多个反射常用的类,下面表格列出了常用的几个类。
类型 | 作用 |
Assembly | 通过此类可以加载操纵一个程序集,并获取程序集内部信息 |
EventInfo | 该类保存给定的事件信息 |
FieldInfo | 该类保存给定的字段信息 |
MethodInfo | 该类保存给定的方法信息 |
MemberInfo | 该类是一个基类,它定义了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多个公用行为 |
Module | 该类可以使你能访问多个程序集中的给定模块 |
ParameterInfo | 该类保存给定的参数信息 |
PropertyInfo | 该类保存给定的属性信息 |
一、System.Reflection.Assembly类
通过Assembly可以动态加载程序集,并查看程序集的内部信息,其中最常用的就是Load()这个方法。
Assembly assembly=Assembly.Load("MyAssembly");
利用Assembly的object CreateInstance(string) 方法可以反射创建一个对象,参数0为类名。
二、System.Type类
Type是最常用到的类,通过Type可以得到一个类的内部信息,也可以通过它反射创建一个对象。一般有三个常用的方法可得到Type对象。
利用typeof() 得到Type对象
Type type=typeof(Example);
利用System.Object.GetType() 得到Type对象
Example example=new Example();
Type type=example.GetType();
利用System.Type.GetType() 得到Type对象
Type type=Type.GetType("MyAssembly.Example",false,true);
注意参数0是类名,参数1表示若找不到对应类时是否抛出异常,参数1表示类名是否区分大小写
例子:
我们最常见的是利用反射与Activator结合来创建对象。
Assembly assembly= Assembly.Load("MyAssembly");
Type type=assembly.GetType("Example");
object obj=Activator.CreateInstance(type);
三、反射方法
1.通过 System.Reflection.MethodInfo能查找到类里面的方法
代码:
Type type=typeof(Example);
MethodInfo[] listMethodInfo=type.GetMethods();
foreach(MethodInfo methodInfo in listMethodInfo)
Cosole.WriteLine("Method name is "+methodInfo.Name);
2.我们也能通过反射方法执行类里面的方法
代码:
Assembly assembly= Assembly.Load("MyAssembly");
Type type=assembly.GetType("Example");
object obj=Activator.CreateInstance(type);
MethodInfo methodInfo=type.GetMethod("Hello World"); //根据方法名获取MethodInfo对象
methodInfo.Invoke(obj,null); //参数1类型为object[],代表Hello World方法的对应参数,输入值为null代表没有参数
四、反射属性
1.通过 System.Reflection.PropertyInfo 能查找到类里面的属性
常用的方法有GetValue(object,object[]) 获取属性值和 SetValue(object,object,object[]) 设置属性值
代码:
Type type=typeof(Example);
PropertyInfo[] listPropertyInfo=type.GetProperties();
foreach(PropertyInfo propertyInfo in listPropertyInfo)
Cosole.WriteLine("Property name is "+ propertyInfo.Name);
2.我们也可以通过以下方法设置或者获取一个对象的属性值
代码:
Assembly assembly=Assembly.Load("MyAssembly");
Type type=assembly.GetType("Example");
object obj=Activator.CreateInstance(type);
PropertyInfo propertyInfo=obj.GetProperty("Name"); //获取Name属性对象
var name=propertyInfo.GetValue(obj,null); //获取Name属性的值
PropertyInfo propertyInfo2=obj.GetProperty("Age"); //获取Age属性对象
propertyInfo.SetValue(obj,34,null); //把Age属性设置为34
五、反射字段
通过 System.Reflection.FieldInfo 能查找到类里面的字段
它包括有两个常用方法SetValue(object ,object )和GetValue(object) 因为使用方法与反射属性非常相似,在此不再多作介绍
(略)
六、反射特性
通过System.Reflection.MemberInfo的GetCustomAttributes(Type,bool)就可反射出一个类里面的特性,以下例子可以反射出一个类的所有特性
代码:
Type type=typeof("Example");
object[] typeAttributes=type.GetCustomAttributes(false); //获取Example类的特性
foreach(object attribute in typeAttributes)
Console.WriteLine("Attributes description is "+attribute.ToString());
通过下面例子,可以获取Example类Name属性的所有特性
代码:
public class Example
{
[DataMemberAttribute]
publics string Name
{get;set;}
..................
}
Type type = typeof(Example);
PropertyInfo propertyInfo=type.GetProperty("Name"); //获取Example类的Name属性
foreach (object attribute in propertyInfo.GetCustomAttributes(false)) //遍历Name属性的所有特性
Console.WriteLine(“Property attribute: "+attribute.ToString());
七、常用实例
虽然反射有很多奥妙之处,但要注意使用反射生成对象会耗费很多性能,所能必须了解反射的特性,在合适的地方使用。最常见例子就是利用单体模式与反射一并使用, 在BLL调用DAL的时候,通过一个反射工厂生成DAL实例。
namespace Project.Common
{
public class Factory
{
//记录dal的对象
private static Hashtable dals;
//用assemblyString记录DAL程序集的全名称
private static string assemblyString = ConfigurationManager.AppSettings["LinqDAL"];
private static Assembly assembly; static Factory()
{
dals = new Hashtable();
assembly = Assembly.Load(assemblyString);
} private static object CreateInstance(string typeName)
{
//当第一次加载时,将反射对象保存于dals集合里
if (!dals.ContainsKey(typeName))
{
//创建反射对象
object object1 = assembly.CreateInstance(typeName); if (object1 == null)
throw new Exception("未能创建此对象");
//把对象加入dals集合
dals["typeName"] = object1;
}
return dals["typeName"];
} public static IExampleDAL CreateExampleDAL()
{
return (IExampleDAL)CreateInstance(assemblyString + ".ExampleDAL");
}
} class Program
{
//利用工厂模式生成对象
static void Main(string[] args)
{
IExampleDAL iExampleDAL=Factory.CreateExampleDAL();
.................
Console.ReadKey();
}
}
} namespace Project.IDAL
{
public interface IExampleDAL
{
///<summary>
/// 插入Example行,若插入成功,则返回新增Example的行数
///</summary>
///<param name="example">Example对象</param>
///<returns>返回新增Example行数,默认值为-1</returns>
int AddExample(Example example); ///<summary>
/// 更新Example表,Update成功返回已经更新的数据条数,失败返回-1
///</summary>
///<param name="example">Example对象</param>
///<returns>Update成功返回已经更新的数据条数,失败返回-1</returns>
int UpdateExample(Example example); ///<summary>
/// 删除Example表中ID等于exampleID的行,返回已删除行数
///</summary>
///<param name="exampleID">Example对象的ID值</param>
///<returns>返回删除行数</returns>
int DeleteExample(int exampleID); ///<summary>
/// 获取Example表的所有行
///</summary>
///<returns>返回Example表中的所有Example对象</returns>
IList<Example> GetList(); ///<summary>
/// 根据ID获取对应Example对象
///</summary>
///<param name="id"></param>
///<returns></returns>
Example GetExampleByID(int id);
}
} namespace Project.DAL
{
public class ExampleDAL:IExampleDAL
{
public int AddExample(Example example)
{
//实现AddExample方法
...........................
}
..................................
..................................
}
}
上面只是介绍了反射的基本用法,当然反射还有很多其他用途,下面几篇文章将为大家一一介绍
NET基础篇——反射的奥妙的更多相关文章
- 转:.NET基础篇——反射的奥妙
反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等程序集内部的信息.使用反射可以看到一个程序集内部的接口.类.方法.字段.属性.特性等等信息.在System.Reflectio ...
- java基础篇---反射机制
一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...
- .NET基础篇——利用泛型与反射更新实体(ADO.NET Entity Framework)(转)
自从ADO.NET Entity Framework面世以来,受到大家的热捧,它封装了大量代码生成的工具,用户只需要建立好实体之间的关系,系统就是会为用户自动成功了Add.Delete.CreateO ...
- Python之路【第十六篇】:Django【基础篇】
Python之路[第十六篇]:Django[基础篇] Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了O ...
- DDD分层架构之领域实体(基础篇)
DDD分层架构之领域实体(基础篇) 上一篇,我介绍了自己在DDD分层架构方面的一些感想,本文开始介绍领域层的实体,代码主要参考自<领域驱动设计C#2008实现>,另外参考了网上找到的一些示 ...
- Python 经典面试题汇总之基础篇
基础篇 1:为什么学习Python 公司建议使用Python,然后自己通过百度和向有学过Python的同学了解了Python.Python这门语言,入门比较简单,它简单易学,生态圈比较强大,涉及的地方 ...
- Java面试题之基础篇概览
Java面试题之基础篇概览 1.一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,且public的类名必须与文件名相一致. 2.Ja ...
- Go语言基础之反射
Go语言基础之反射 本文介绍了Go语言反射的意义和基本使用. 变量的内在机制 Go语言中的变量是分为两部分的: 类型信息:预先定义好的元信息. 值信息:程序运行过程中可动态变化的. 反射介绍 反射是指 ...
- 01: Django基础篇
目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...
随机推荐
- VS中子对话框的关闭回调函数
新建了QDialog的子类时,如果需要回调它的关闭函数 1.加入头文件#include <QCloseEvent> 2.重写函数 protected: void closeEvent(QC ...
- JDK 1.8 ConcurrentHashMap 源码剖析
转载两篇不错的文章: 第一篇: 前言 HashMap是我们平时开发过程中用的比较多的集合,但它是非线程安全的,在涉及到多线程并发的情况,进行put操作有可能会引起死循环,导致CPU利用率接近100%. ...
- C++ 中的关于输出的设置于
▲setw(n)用法: 通俗地讲就是预设宽度 如 cout<<setw(5)<<255<<endl; 结果是: (空格)(空格)255 ▲setfill(char ...
- 过了所有技术面,却倒在 HR 一个问题上
面试问离职原因,这是我们广大程序员朋友面试时逃不开的问题,如果答得不好,可能就影响了你整个的面试结果. 最近在群里,我也看到大家在讨论这个问题,其中有个朋友的回复很有感触,我分享给大家看一下. 如图, ...
- Java Spring-事务管理
2017-11-12 16:31:59 Spring的事务管理分为两种: 编程式的事务管理:手动编写代码 声明式的事务管理:只需要配置就可以 一.最初的环境搭建 public interface Ac ...
- HTML DOM知识点补充:
DOM Console 控制台对象提供了浏览器的debug的方法支持. 常用的:console.log(). ⚠️coffeescript中,这个方法不加括号. DOM Document 当一个HTM ...
- 识别TLS加密恶意流量
利用背景流量数据(contexual flow data)识别TLS加密恶意流量 识别出加密流量中潜藏的安全威胁具有很大挑战,现已存在一些检测方法利用数据流的元数据来进行检测,包括包长度和到达间隔时间 ...
- Laravel框架中Validor中错误信息$error的输出
@if (count($errors) > 0) <div class="alert alert-danger"> <ul> @foreach ($e ...
- Nginx笔记02-nginx常用参数配置说明
nginx的主配置文件是nginx.conf,这里主要针对这个文件进行说明 1.主配置文件nginx.conf 2.nginx配置文件的结构 从上面的配置文件中我们可以总结出nginx配置文件的基 ...
- android 知识小结-1
Java哪些数据结构是线程安全的,CurrentHashMap的原理 ConcurrentHashMap.ConcurrentSkipListMap.ConcurrentSkipListSet.Con ...