程序集与反射技术(C#)
首先我们来看程序集,程序集是代码进行编译是的一个逻辑单元,把相关的代码和类型进行组合,然后生成PE文件(例如可执行文件.exe和类库文件.dll)。由于程序集在编译后并不一定会生成单个文件,而可能会生成多个物理文件,甚至可能会生成分布在不同位置的多个物理文件,所以程序集是一个逻辑单元,而不是一个物理单元。即程序集在逻辑上是一个编译单元,但在物理储存上可以有多种存在形式。对于静态程序集可以生成单个或多个文件,而动态程序集是存在于内存中的。在C#中程序集处处可见,因为任何基于.NET的代码在编译时都至少存在一个程序集(所有.NET项目都会默认引用mscorlib程序集)。
基于.NET框架的.dll库是一个完整的程序集,需要事先引用对应的类库。从代码的结构上看,一个程序集可以包含一个或多个命名空间,而每个命名空间中又可以包含子命名空间或类型列表。由于程序集在编译后可以生成多个模块文件,因此一个物理文件并不代表它就是一个程序集,一个程序集并不一定只有一个文件。不过,在VS开发环境中,一个解决方案可以包含多个项目,而每个项目就是一个程序集。
程序集信息其实是通过在程序集上应用各种Attribute来设置的,并且这些特性都位于System.Reflection命名空间,也就是这一系列Attribute提供给反射技术,可用于获取程序集的基本信息.
应用程序结构分为应用程序域—程序集—模块—类型—成员几个层次,公共语言运行库加载器管理应用程序域,这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局。
程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。反射通常具有以下用途。
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。
(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
动态加载程序集:
(1)通过程序集的长名称加载,一般用于加载位于全局程序集缓存中的程序集。(.NET框架的类库都位于全局程序集缓存中)(使用GacUtil命令行工具可以获取System程序集的长名称);
(2)通过指定的文件加载程序集,通常是.dll或.exe文件。
例如:本人的计算机上的全局程序集缓存包含下列程序集:
system, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL
system, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL
项目数 = 2
反射(Reflection)是.NET中的重要机制,通过反射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数等。有了反射,即可对每一个类型了如指掌。如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道。
1)反射用于获取类型信息。下面一个例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection; namespace My
{
class Program
{
static void Main(string[] args)
{
// 加载程序集
Assembly ass = Assembly.Load("system.windows.forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
// 获取Button类的Type
Type typeofButton = ass.GetType("System.Windows.Forms.Button", false);
if (typeofButton != null)
{
// 获得Button类型的公共属性列表
PropertyInfo[] props = typeofButton.GetProperties();
// 输出属性信息
Console.WriteLine("\n Button类的公共属性列表:");
foreach (PropertyInfo p in props)
{
Console.WriteLine(" 属性名:{0},属性类型:{1}", p.Name, p.PropertyType.Name);
}
// 获取Button类型的公共事件列表
EventInfo[] events = typeofButton.GetEvents();
// 输出事件信息
Console.WriteLine("\n Button类的公共事件列表:");
foreach (EventInfo ev in events)
{
Console.WriteLine(" 事件名:{0},事件类型:{1}", ev.Name, ev.EventHandlerType.Name);
}
}
Console.Read();
}
39 }
}
2)反射还可以在运行阶段动态创建类型实例,然后就可以动态调用实例的成员。
动态创建实例有两种方法可以选择:
第一种:使用Activator类的CreateInstance静态方法,其中方法返回的对象就是对应的实例引用。
看个例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection; namespace Me
{
class Program
{
static void Main(string[] args)
{
// 从当前执行的程序集中获取Test类型的Type
Assembly ass = Assembly.GetExecutingAssembly();
Type tp = ass.GetType("Me.Test", false);
if (tp != null)
{
// 创建实例
object instance = Activator.CreateInstance(tp, );
if (instance != null)
{
// 获取实例的公共属性
PropertyInfo[] props = tp.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// 显示属性信息
foreach (var p in props)
{
Console.WriteLine("{0} : {1}", p.Name, p.GetValue(instance));
}
}
} Console.Read();
}
}
public class Test
{
public int NumValue { get; private set; } public Test(int sead)
{
Random rand = new Random(sead);
NumValue = rand.Next();
}
}
}
第二种:通过反射找出类型的构造函数,然后调用构造函数来获取实例引用。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection; namespace My
{
class Program
{
static void Main(string[] args)
{
// 从mscorlib程序集中获取DateTime结构的Type
Type tpdatetime = Type.GetType("System.DateTime", false);
if (tpdatetime != null)
{
// 获取具有六个参数的构造函数
ConstructorInfo constructor = tpdatetime.GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });
if (constructor != null)
{
// 调用构造函数创建实例
object instance = constructor.Invoke(new object[] { , 9, , , , });
// 获取实例的属性列表
if (instance != null)
{
PropertyInfo[] props = tpdatetime.GetProperties(BindingFlags.Public | BindingFlags.Instance);
Console.WriteLine("以下是DateTime实例的属性值列表:");
foreach (PropertyInfo p in props)
{
// 获取属性值
object objval = p.GetValue(instance);
// 显示属性名称与属性值
Console.WriteLine("{0,-15} :{1}", p.Name, objval ?? string.Empty);
}
}
}
} Console.Read();
}
}
}
学习到这里,相信你已经对这部分知识有啦相当一部分了解,由于是第一次写博客,或许写的不是很好,若有错,请联系我,下期再见。。。。
程序集与反射技术(C#)的更多相关文章
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- C#反射技术概念作用和要点
反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...
- 【转】.Net中通过反射技术的应用----插件程序的开发入门
转自:http://www.cnblogs.com/winloa/archive/2012/03/25/2416355.html .Net中通过反射技术的应用----插件程序的开发入门 再开始之前,先 ...
- C# 反射技术应用
反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...
- 用反射技术替换工厂种的switch分支(14)
首先给大家拜个晚年,祝大家新春快乐,万事如意,鸡年大吉. 好了,前面我们讲了很多的工厂模式,其中,有个很明显的特点,工厂中,有一个方法,里面有很多的swich case 分支,我们前面说过,我们可以 ...
- 深入浅出 .NET C# 反射技术
反射这个词听起来就很牛逼是吧? 嗯的确,反射是比较高级的特性,只有语言基础很扎实的Dev们才应该使用它. 搞点反射,可以提高程序的灵活性.可扩展性.耦合度. 反射这东西,是为了动态地运行时加载,相比于 ...
- 【Android测试】【第十七节】Instrumentation——App任你摆布(反射技术的引入)
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5569844.html 前言 学习了上节之后,大家是否已经 ...
- 黑马程序员:Java编程_反射技术
=========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性 ...
- java 反射技术
什么是反射?反射就是将字节码中的各种成分映射到相应的java类中来,java反射技术自JDK1.1以来就出现了,目前大多数流行的框架都采用了这种技术,可见其重要性,这篇文章将详细介绍我对java反射技 ...
随机推荐
- Windows驱动开发技术详解HelloWDM例子win7下无法安装
HelloWDM例子编译完成之后,在win7下安装显示 查看setupapi.dev看到如下信息 这个C:\MyDriver_Check目录完全不是我指定的,我放到c盘根目录下 查看inf [Sour ...
- Excel导入导出组件的设计
前言: 距离一篇文章,又八九个月过去了,随着在园子露脸的次数越来越少,正如我们淡忘上一波大神那样,我们也正下一波所淡忘. 这八九个月,前前后,游走在十来个项目上,忙,却找不到成就感. 人过30后,也是 ...
- Visual Studio 2013 Ultimate的可视化代码功能
可视化和了解代码综合了如何使用visual studio可视化代码来帮助理解代码: 理解代码和代码之间的关系:(1)Code Map(2)Dependency Graphs 理解代码交互:Sequen ...
- Python黑帽编程2.6 模块
Python黑帽编程2.6 模块 我们已经学习了如何在你的程序中定义一次函数而重用代码.如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块.模块基本上就是一个 ...
- [每日电路图] 10、两种MOS管的典型开关电路
下图是两种MOS管的典型应用:其中第一种NMOS管为高电平导通,低电平截断,Drain端接后面电路的接地端:第二种为PMOS管典型开关电路,为高电平断开,低电平导通,Drain端接后面电路的VCC端. ...
- .Net组件程序设计之对象生命周期
.Net组件程序设计之对象生命周期 .NET 垃圾回收 IDisposable() Using语句 .NET 垃圾回收 是CLR管理着垃圾回收器,垃圾回收器监控着托管堆,而我们使用的对象以及系统启动是 ...
- ASP.NET MVC 5 - 控制器
MVC代表: 模型-视图-控制器 .MVC是一个架构良好并且易于测试和易于维护的开发模式.基于MVC模式的应用程序包含: · Models: 表示该应用程序的数据并使用验证逻辑来强制实施业务规则的数据 ...
- AMD规范与CMD规范的区别
AMD规范与CMD规范的区别是什么? 在比较之前,我们得先来了解下什么是AMD规范?什么是CMD规范?当然先申明一下,我个人也是总结下而已,也是网上看到的资料,自己总结下或者可以说整理下而已,供 ...
- iOS 之APP上架
前几天在忙着上线,尽管之前已经上线过一次,但由于本身比较菜,还是状况百出. 好在今天终于成功提交,因此来写写心得. 如果是第一次上线,推荐这篇文章: http://jingyan.baidu.com/ ...
- 《Qt Quick 4小时入门》学习笔记3
http://edu.csdn.net/course/detail/1042/14807?auto_start=1 Qt Quick 4小时入门 第八章:Qt Quick中的锚(anchors)布局 ...