第十章 管理类型(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. 声明式事务管理:在此,事务管理与业务代码分离.仅 ...
随机推荐
- MapHttpRoute
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Http/HttpRouteCollectionExten ...
- Activity代码结构
把一个Nova项目中典型的Activity代码结构简单归纳一下,保持代码风格的一致,有助于日常开发效率提升以及日后维护 Class Name 变量 constants requests ...
- 内省—beanutils工具包
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写. BeanU ...
- MFC学习 进程间通信
内存共享通信方式 server.cpp #include <stdio.h> #include <Windows.h> int main() { HANDLE hFile; h ...
- android EditText 只允许输入指定字符
实现只允许只入数字和字符 方法一:在XML文件中实现布局如下: <EditText android:layout_width="match_parent" android:l ...
- jmeter随笔(23)--在csv中维护变量参数
点击标题下「蓝色微信名」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是 ...
- 飞达资讯App总体介绍及关系架构图
飞达资讯App总体介绍: 下图为飞达资讯App的关系架构图: 该App关系架构图所需的图片云盘链接地址:http://pan.baidu.com/s/1gfHIe4b 提取密码:x1nr 该App的云 ...
- Deviceone:站在移动互联时代的十字路口上
最近总能看到类似“App已死,服务永生”.“App必死,web永生” .“App已死,微信建站已生”这样的文章.不晓得这些网络写手到底是想代表某些公司的立场.还是想要表达怎么样的一个情结,文章中语气都 ...
- port-channel和channel-group
cisco交换机上的链路聚合 2层 ethernet channel (interface)#channel-group number mode {on | auto [no-silent]|desi ...
- phpinfo中查不到memcache信息问题
已经安装了php的memcache扩展,可是怎么都不能通过phpinfo查询到,实际使用时提示扩展未安装.为什么呢?百般寻求解决方法,才发现主要有以下两点原因: 1.使用的php和安装扩展的php不是 ...