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 ...
随机推荐
- constructor-arg和property的区别
两者都是给bean注入属性,区别: constructor-arg:通过构造函数注入. property:通过setter对应的方法注入. 详情见:https://blog.csdn.net/u012 ...
- ubuntu16.04+七彩虹GTX1060的NVIDIA驱动+Cuda8.0+cudnn5.1+tensorflow+keras搭建深度学习环境【学习笔记】【原创】
平台信息:PC:ubuntu16.04.i5.七彩虹GTX1060显卡 作者:庄泽彬(欢迎转载,请注明作者) 说明:参考了网上的一堆的资料搭建了深度学习的开发环境,下班在宿舍折腾了好几个晚上才搞定,写 ...
- (转载)YOLO配置文件理解
YOLO配置文件理解 转载自 [net] batch=64 每batch个样本更新一次参数. subdivisions=8 如果内存不够大,将batch分割为subdivisions个子batch,每 ...
- python 使用两个列表合成字典
keys = ['red', 'green', 'blue'] values = ['#FF0000','#008000', '#0000FF'] color_dictionary = dict(zi ...
- [转]如何使用VS 2013發布一個可以在Windows XP中獨立運行的可執行文件
https://read01.com/Mg337.html (台/湾的论坛,需要f/q) 1. 閱讀此文章的同學先看看我的另外一篇文章: 現在,我們深入探討一下: <如何使用VS 2013發布一 ...
- Flutter基础Widget之按钮(RaisedButton、FlatButton、OutlineButton,IconButton)
Flutter中给我们预先定义好了一些按钮控件给我们用,常用的按钮如下 RaisedButton :凸起的按钮,其实就是Android中的Material Design风格的Button ,继承自Ma ...
- tenserflow models包的安装
1.下载 models包 https://github.com/tensorflow/models 2.将models包拷贝到本机Python包的安装地址即可,本机Python包的安装地址的查看方式可 ...
- Rails 5 Test Prescriptions 第9章 Testing-JavaScript: Integration Testing,❌挂一个问题webpacker::helper
使用Capybara进行JS的集成测试 谈论驱动 让测试通过 Webpack in Development Mode Js设计 是用户在网页上有好的体验的重要因素. 尽管如此,许多网页不测试JS. 部 ...
- Xmind8 (update8)破解教程
环境:Win7 一.下载xmind: Xmind版本:xmind-8-update8-windows.exe 百度云盘地址: https://pan.baidu.com/s/1ccd18E1hOY1 ...
- 水晶报表VS2010防止出现用户登录问题
1.联合查询,采用视图办法 2.借用如下语句 using CrystalDecisions.CrystalReports.Engine; using CrystalDecisions.Shared; ...