第十章 管理类型(In .net4.5) 之 使用反射
1. 概述
一个.net程序不仅包含代码和数据,还包含 元数据。
本章介绍如何应用attributes以及如何使用反射来获取它,还有如何使用CodeDom和expression trees来实现在运行时生成代码。
2. 主要内容
2.1 创建和使用attributes
① attributes用来向程序添加元数据。可以应用到所有类型:程序集、类、方法、参数、属性。
[Conditional("CONDITION1"), Conditional("CONDITION2")]
static void MyMethod() { }
② AssemblyInfo.cs中保存的是应用到当前程序集的所有attributes。
③ 可以使用attributes的IsDefined和GetCustomAttribute方法读取attributes
if (Attribute.IsDefined(typeof(Person), typeof(SerializableAttribute)))
{ } ConditionalAttribute conditionalAttribute =
(ConditionalAttribute)Attribute.GetCustomAttribute(
typeof(ConditionalClass),
typeof(ConditionalAttribute)); string condition = conditionalAttribute.ConditionString; //CONDITION1
④ 可以自定义attributes
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
AllowMultiple=true)]
class CompleteCustomAttribute : Attribute
{
public CompleteCustomAttribute(string description)
{
Description = description;
}
public string Description {get; set; }
}
2.2 使用反射
反射 使得一个应用程序可以收集自身的信息并使用。反射的运行速度比其他静态代码慢。
public interface IPlugin
{
string Name { get; }
string Description {get; }
bool Load(MyApplication application);
} Assembly pluginAssembly = Assembly.Load("assemblyName"); var plugins = from type in pluginAssembly.GetTypes()
where typeof(IPlugin).IsAssignableFrom(type) && !type.IsInterface
select type; foreach(Type pluginType in plugins)
IPlugin plugin = Activitor.CreateInstance(pluginType) as IPlugin;
使用反射还可以获取属性的值和执行指定的方法。
int i = ;
MethodInfo compareToMethod = i.GetType().GetMethod("CompareTo"
, new Type[] { typeof(int) };
int result = (int)compareToMethod.Invoke(i, new object[] { });
2.3 使用CodeDom和Lambda表达式生成代码
① 使用CodeDom
CodeCompileUnit compileUnit = new CodeCompileUnit();
CodeNamespace myNamespace = new CodeNamespace("MyNamespace");
myNamespace.Imports.Add(new CodeNamespaceImport("System"));
CodeTypeDeclaration myClass = new CodeTypeDeclaration("MyClass");
CodeEntryPointMethod start = new CodeEntryPointMethod();
CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("Console"), "WriteLine", new CodePrimitiveExpression("Hello World!")); compileUnit.Namespaces.Add(myNamespace);
myNamespace.Types.Add(myClass);
myClass.Members.Add(start);
start.Statements.Add(cs1);
编译单元定义完成后,使用CSharpCodeProvider来执行生成。
CSharpCodeProvider provider = new CSharpCodeProvider();
using(StreamWriter sw = new StreamWriter("HelloWorld.cs", false))
{
IndentedTextWriter tw = new IndentedTypeWriter(sw, " ");
provider.GenerateCodeFromCompileUnit(compileUnit, tw, new CodeGeneratorOptions());
tw.Close();
}
② 使用 expression trees 实现上述功能
BlockExpression blockExpr = Expression.Block(
Expression.Call(
null,
typeof(Console).GetMethod("Write", new Type[] { typeof(String)}), Expression.Constant("Hello ")
),
Expression.Call(
null,
typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String)}), Expression.Constant("World!")
),
); Expression.Lambda<Action>(blockExpr).Compile();
3. 总结
① 一个C#程序集包括代码和元数据。
② Attributes是元数据的一种,可以被应用到代码中,可以在运行时被查询到。
③ 反射是一个在C#程序中检查元数据的过程。
④ 利用反射,可以 创建类型、调用方法、读取属性 等等。
⑤ CodeDom用于在运行时创建一个编译单元。可以被编译或转化成源码文件。
⑥ 表达式树 描述一块代码,可以被翻译成其他语言(比如sql),也可以被编译和执行。
第十章 管理类型(In .net4.5) 之 使用反射的更多相关文章
- 第十一章 管理类型(In .net4.5) 之 管理对象的生命周期
1. 概述 本章内容包括 管理非托管资源.使用IDisposable接口 以及 管理析构器和垃圾回收. 2. 主要内容 2.1 理解垃圾回收机制 ① 代码执行的时候,内存中有两个地方存放数据项:堆 和 ...
- 第十二章 管理类型(In .net4.5) 之 操作字符串
1. 概述 本章包括 字符串基本操作 以及 查找.遍历.格式化字符串. 2. 主要内容 2.1 在.net平台中使用字符串 C#中,string是用来保存文本信息的.是一个被当做值类型使用的引用类型. ...
- 第八章 管理类型(In .net4.5) 之 加强封装
1. 概述 本章内容包括 访问控制符.属性 和 显式接口实现. 2. 主要内容 2.1 访问控制符 封装的核心是隐藏信息.访问控制符用来实现类型成员的访问控制. C#的访问控制符有:public, i ...
- 第七章 管理类型(In .net4.5) 之 使用类型
1. 概述 本章介绍 值类型的装箱拆箱.类型转换 以及 C#4.0新推出的 dynamic 关键字. 2. 主要内容 2.1 装箱和拆箱 2.2 类型转换 有四种方式可以实现类型转换: ① 隐式转换: ...
- 第六章 管理类型(In .net4.5) 之 创建类型
1. 概述 本章内容包括 C#5中如何更好的创建类型以及如何扩展现有类型. 2. 主要内容 2.1 如何选择类型 C#类型系统包括三种类型:值类型.引用类型.指针类型.(指针类型用于非托管代码,很少使 ...
- 第九章 管理类型(In .net4.5) 之 继承机制
1. 概述 本章包括 设计和实现接口.创建和使用基类 以及 使用.net类库提供的标准接口. 2. 主要内容 2.1 设计和实现接口 一个接口包含公共的方法.属性.事件.索引器.类和结构都可以实现接口 ...
- EJB3 EntityBean中EntityManager的管理类型
EJB中EntityManager的管理方式有两种:Container-managed EntityManager和Application-managed EntityManager 即容器管理的En ...
- Spring支持的事务管理类型?
Spring支持两种类型的事务管理: 编程式事务管理 :这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护. 声明式事务管理: 这意味着你可以将业务代码和事务管理分离,你只需用注解和XM ...
- 列举 spring 支持的事务管理类型?
Spring 支持两种类型的事务管理: 1. 程序化事务管理:在此过程中,在编程的帮助下管理事务.它为您提供极大 的灵活性,但维护起来非常困难. 2. 声明式事务管理:在此,事务管理与业务代码分离.仅 ...
随机推荐
- UIView之基础控件综合事例
九宫格算法实现及优化 2015年11月19日 星期四 23:21 1.九宫格之初实现 要求: 1.1在主界面中,点击添加按钮就能添加商品,点击删除按钮就能删除商品; 1.2在初始化界面中,添加按钮处于 ...
- H264句法和语法总结(二)NAL层语法
1.NAL全称Network Abstract Layer, 即网络抽象层. 在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面(N ...
- Linux学习小结(转)
linux目录架构 / 根目录/bin 常用的命令 binary file 的目錄/boot 存放系统启动时必须读取的档案,包括核心 (kernel) 在内/boot/grub/menu.l ...
- SICP 1.1-1.5
1.1 a = b = nil 1.2 (/ (+ (- (- (+ (/ ))))) (* (- ) (- )) 1.3 a = b = nil 1.4... 1.5 (define (p) (p) ...
- Flash与IE奇怪的关键字冲突
我有一个小小的swf文件,用来播放声音,加入到HTML后,在Firefox/chrome下播放正常,唯独IE8提示 消息: 对象不支持此属性或方法 行: 48 字符: 3 代码: 0 URI: ... ...
- iis 站点部署后 Microsof .Net Framework异常
最近在部署站点到 iis 中时,遇到 iis 崩溃的问题,一打开部署好 的站点后,就出现 Microsoft .Net Framework 异常的消息提示,具体的 异常情况如下: 于是在网上查找了很多 ...
- 跟我学 NHibernate (一)
NHibernate 是一个强大的 ORM 框架,本博文主要就 NHibernate 的使用方法及语法做一些简单的介绍. 1.NHibernate 语法 新建一个类,命名为: QueryCrit ...
- org.springframework.jdbc.BadSqlGrammarException
org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLExc ...
- LED点阵显示名字
学习了一周的单片机,然后中途有事打断了两周,现在温习一下之前学的东西,用“普中科技单片机”上的LED点阵显示自己的名字. P1接J19(绿).P2接J20(红),P0接J12(数码管段选):5V电压: ...
- APUE第一章_课后习题
/* 未完成的:1.5 不过在下文中已经给出了解答. */ 1.1 在系统上查证,除根目录外,目录.和..是不同的 ans:这个很容易,用vim打开.和..就可以看到区别. 1.2 分析程序清单1-4 ...