1. 概述

  一个.net程序不仅包含代码和数据,还包含 元数据

  本章介绍如何应用attributes以及如何使用反射来获取它,还有如何使用CodeDomexpression 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) 之 使用反射的更多相关文章

  1. 第十一章 管理类型(In .net4.5) 之 管理对象的生命周期

    1. 概述 本章内容包括 管理非托管资源.使用IDisposable接口 以及 管理析构器和垃圾回收. 2. 主要内容 2.1 理解垃圾回收机制 ① 代码执行的时候,内存中有两个地方存放数据项:堆 和 ...

  2. 第十二章 管理类型(In .net4.5) 之 操作字符串

    1. 概述 本章包括 字符串基本操作 以及 查找.遍历.格式化字符串. 2. 主要内容 2.1 在.net平台中使用字符串 C#中,string是用来保存文本信息的.是一个被当做值类型使用的引用类型. ...

  3. 第八章 管理类型(In .net4.5) 之 加强封装

    1. 概述 本章内容包括 访问控制符.属性 和 显式接口实现. 2. 主要内容 2.1 访问控制符 封装的核心是隐藏信息.访问控制符用来实现类型成员的访问控制. C#的访问控制符有:public, i ...

  4. 第七章 管理类型(In .net4.5) 之 使用类型

    1. 概述 本章介绍 值类型的装箱拆箱.类型转换 以及 C#4.0新推出的 dynamic 关键字. 2. 主要内容 2.1 装箱和拆箱 2.2 类型转换 有四种方式可以实现类型转换: ① 隐式转换: ...

  5. 第六章 管理类型(In .net4.5) 之 创建类型

    1. 概述 本章内容包括 C#5中如何更好的创建类型以及如何扩展现有类型. 2. 主要内容 2.1 如何选择类型 C#类型系统包括三种类型:值类型.引用类型.指针类型.(指针类型用于非托管代码,很少使 ...

  6. 第九章 管理类型(In .net4.5) 之 继承机制

    1. 概述 本章包括 设计和实现接口.创建和使用基类 以及 使用.net类库提供的标准接口. 2. 主要内容 2.1 设计和实现接口 一个接口包含公共的方法.属性.事件.索引器.类和结构都可以实现接口 ...

  7. EJB3 EntityBean中EntityManager的管理类型

    EJB中EntityManager的管理方式有两种:Container-managed EntityManager和Application-managed EntityManager 即容器管理的En ...

  8. Spring支持的事务管理类型?

    Spring支持两种类型的事务管理: 编程式事务管理 :这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护. 声明式事务管理: 这意味着你可以将业务代码和事务管理分离,你只需用注解和XM ...

  9. 列举 spring 支持的事务管理类型?

    Spring 支持两种类型的事务管理: 1. 程序化事务管理:在此过程中,在编程的帮助下管理事务.它为您提供极大 的灵活性,但维护起来非常困难. 2. 声明式事务管理:在此,事务管理与业务代码分离.仅 ...

随机推荐

  1. PHP截取IE浏览器并缩小原图的方法

    这篇文章主要介绍了PHP截取IE浏览器并缩小原图的方法,涉及PHP调用com组件实现图像截取的相关技巧,需要的朋友可以参考下 本文实例讲述了PHP截取IE浏览器并缩小原图的方法.分享给大家供大家参考, ...

  2. 【翻译习作】 Windows Workflow Foundation程序开发-第一章04

    1.2.3  Windows Workflow运行时 从Windows Workflow的角度看,可以将工作流活动当成是交给一个工作流处理器去执行的一系列指令或操作码.在Windows Workflo ...

  3. uLua Unity工作机制

    基于ulua 1.25版本,开启C#类型动态注册. 一.  步骤 注册需要Wrap的C#类型. 在WrapFile.cs类中,使用_GT(typeof(XXX)), 注册需要Wrap的C#类型 注册的 ...

  4. Maven中央存储库

    当你建立一个 Maven 的项目,Maven 会检查你的 pom.xml 文件,以确定哪些依赖下载.首先,Maven 将从本地资源库获得 Maven 的本地资源库依赖资源,如果没有找到,然后把它会从默 ...

  5. VB datagrid指定行着色

    有图有真相: 关键点:使用datagrid的FetchRowStyle委托. (Form界面的datagrid名称:dgv) 使用FetchRowStyle委托,要先打开开关: dgv.FetchRo ...

  6. mysql中字符集和校对规则

    首先,明确一下字符集和校对规则的概念:    字符集(charset):是一套符号和编码    校对规则(collation):是在字符集内用于比较字符的一套规则,比如有的规则区分大小写,有的则无视 ...

  7. DWR基本配置

    DWR——Direct Web Remoter Servlet 供给那些想要以一种简单的方式使用Ajax和XMLHttpRequest的开发者.它具有一套JavaScript功能集,它们把从HTML页 ...

  8. asp.net解决数据转换为DBNULL的问题

    if (string.IsNullOrEmpty(CookieHelper.GetCookie("DEPID", "theway").ToString()) = ...

  9. Windows7:Visual Studio 2008试用版的评估期已经结束解决方法

    Windows7:Visual Studio 2008试用版的评估期已经结束解决方法       以前在Windows2003碰到这个问题时,都是到"控制面板→添加或删除程序"选择 ...

  10. 使用Servlet处理请求<http://blog.sina.com.cn/s/blog_5d3fb3cc0100ep9q.html>

    一.GET和POST的区别 1.GET提交的是文本内容,规定其数据长度不超过255个字符.在GET方式提交的URL中会显示出提交的查询数据而却提交数据的缓存会在浏览器的URL历史状态中,这样我们往往在 ...