【.net 深呼吸】细说CodeDom(1):结构大观
CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧。DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了。如果你从来没接触过 CodeDom,你大概可以根据这个名字,推断它应该和代码文档模型有关。
这推断是靠谱的,CodeDom的功能,老周厚着脸皮把它归结为两大部分:
1、生成代码文档。这个听起来很玄?不玄,就是咱们在VS里常常耍的代码生成,比如你添加了一个服务引用,VS会帮你生成一个客户端代理类。
2、动态编译程序集。这个也好懂,就是动态编译。
很多朋友一遇到这个就怕,很难,很复杂。其实不然,CodeDom并不难,把思路理清了就好学了,这个事咱们暂时不谈,先说说老周要写的这系列文章吧,简单抛个砖,引个玉,免得大伙到时候向老周扔砖。
其实老周在几个世纪前曾在其他的博客上写过 CodeDom 相关的文章,大家也不要去人肉那些文章了,都是很肤浅很烂的文章,只是XX几笔就写完了,初学者朋友肯定看不懂的。没办法了,几个世纪前老周的编程水平比较烂,有时候翻开自己以前写的东西,都觉得很搞笑,自己当年怎么写这么SB的文章。
为了让更多朋友能够看懂,也为了向传统的编程教学方式发起挑战,有关CodeDom这系列文章,老周计划开启【废话模式】,老周会尽可能进行细致的讲解,到时候你不要觉得烦,废话会很多的。正因为废话多,所以一两篇文章肯定写不完的,至少得来个中篇小说的容量才行。
============================================
好,下面开始讲废话。
作为废话系列的第一篇,老周不会马上让你动手写代码的,既然是跟代码文档有关的东西,那就先复习一下代码的基础知识,很重要的,赶紧划重点,期末考试一定会考的。我的大学老师在上复习课的时候,老喜欢说这句话。记得当年老周就是不划重点,所以考了48.5分,然后被抓去补考,补考考了66分,形式上不用重修,于是就天下大吉了。上大学时,老周对考试从来都没认真过,包括考英语四级,作文里面还写上粗口,不知道阅卷老师看到之后会不会血压上升。
细细想一想,真不知道考试是为了什么,考60分又如何,考100分又如何,不还是一样吗。老周是出了名的上课不听课,复习不认真,考试不重视,哪怕面对高考也一样。但是老周绝不是不认真学习的人,只是跟贾宝玉差不多,怕看正经书,对于正经书以外的很多东西,老周反而很用功。
老周这个人,没什么优点,长得不帅(眼睛小,嘴巴扁,鼻子高),又不富(当年那张中信银行卡上时刻保持余额1.33元),1米78的身材也不高。唯一的优点就是兴趣广,爱好多,杂学旁收,从不客气,只要别让我读教材做考试题就行。
所以当年有妹子就写了一首诗来形容老周:
不爱烟酒不羡富,苦学逸少子昂书。
酷喜上课看杂志,最怕临考背试题。
偶得仙乐歌一阙,沉思漫笔有洞天。
CodeDom支持如C#、VB、C++、JScript这几种语言的代码生成,当然,必须是生成CLR能认识的代码,所以这里头的C++主要是托管C++。
现在,你开始回忆一下,满怀深情地回忆一下,一个CLR程序集里面有什么?由于在VS里面,一个项目就是一个程序集,或者你可以想一下,一个项目的代码里面有啥。
咱们从外向里一层一层的刷一下。
A、一个项目中是不是有N个命名空间?想起来了吧,而命名空间里面可以包括命名空间,不过,CodeDom中不使用嵌套命名空间,比如,System和System.IO可以认为是两个单独的命名空间。
B、然后,大伙再想想,一个命名空间下有啥。类型,好,类型又有多少种?数一数,类、结构、枚举、接口、委托。
C、类型下面有什么?对,成员,那么类型成员有几种。再数一数,构造函数、字段、属性、方法、事件。
1)如果类型是泛型类型,还会包含若干泛型列表,泛型参数可能还带有约束。
2)如果成员是方法,会包含有输入参数、输出参数或返回值;对于属性成员,会有get和set访问器。对于索引器,会有索引变量。
D、类型成员下包含语句集合(Statement),通常翻译为语句比较好听。常规代码语句以英文的分号(;)结束,这个大家都很熟悉了,当然,像if、while、for这些语句比较特别,它们往往包含多个条件。
E、语句是由表达式和运算符(操作符)组成。
比如,这样就是一个表达式,常量表达式。
这样就是一个语句,赋值语句。
- k = ;
这是语句,它包括一个 = 运算符(赋值运算符),一个变量引用表达式(k),以及一个常量表达式(300)。
有一个语句大家要注意,就是这样:
- double x = 0.0021d;
别看它很简单,别看它是很基础的知识,这里面的门道你还真未必已经掌握。
它是一个复合语句,其实它包含两个语句:声明语句(double x;),赋值语句(x = 0.0021d)。如果拆开来,可以这样写。
- double x;
- x = 0.0021d;
而 double x = 0.0021d 是在变量声明时顺便进行初始化。在两种写法在 CodeDom 代码生成中是应当区别,这个后续的文章中老周会讲的,现在你暂时了解一下。
好,代码的结构大观我们复习完了,老周保证你期末考试能考95分。
既然是要讲CodeDom的,就得把代码结构中的各个对象与CodeDOM类型对号入座,这样可以方便大家熟悉CodeDom模型。
来,先喝杯牛奶,做好准备,下面开始接触 CodeDom了。
=========================================
CodeDom 的根容器是 CodeCompileUnit,它是一个编译单元,这个类你必须认识,不然以后就无法CodeDom了,如果要进行动态编译,就应该用一个编译单元来编译,不能用一句代码来编译,因为这样生成的程序没有实际意义,也不能运行。
编译单元你可以把它类比一个VS项目,一个程序集。所以,你会看到,CodeCompileUnit 类有一个 Namespaces 属性,这使得一个编译单元可以包含 N 个命名空间。
一个命名空间可以用 CodeNamespace 类来表示,Comments 用来设置给命名空间写的注释,Imports就是这个命名空间中要引入的其他命名空间,就是C#中的 using,VB中的 Import,托管C++中的 using。
一个 CodeNamespace 类公开了 Types 属性,表示某个命名空间下的类型集合。要声明一个类型,使用 CodeTypeDeclaration 类,至于定义的是类,是接口,还是枚举,可以用类的属性来决定。例如IsInterface指定是否为接口,IsClass指定是否为类,IsEnum指定是否为枚举等。如果类是从其他类型派生的,或者实现接口,那可以向BaseTypes属性添加基类型。如果基类是Object,可以忽略。
但是,委托类型的声明比较特殊,它使用 CodeTypeDelegate 类。
一个类型之下包含的是类型成员,它们对应的CodeDom类有:CodeMemberField(字段)、CodeMemberProperty(属性)、CodeMemberMethod(方法)、CodeMemberEvent(事件)。
注意,表示类型构造函数有两个类。如果是静态构造函数,因为它是属于类型而非实例,所以要用 CodeTypeConstructor;对于普通面向实例的构造函数要使用 CodeConstructor。
好了,今天就讲到这里吧,讲多了,大伙会接受不了。下一篇文章,老周再介绍代码表达式和代码语句。
【.net 深呼吸】细说CodeDom(1):结构大观的更多相关文章
- 【.net 深呼吸】细说CodeDom(8):分支与循环
有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类.要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的.如果用.net的“反编译”工具 ...
- 【.net 深呼吸】细说CodeDom(3):命名空间
在上一篇文章中,老周介绍了表达式和语句,尽管老周没有把所有的内容都讲一遍,但相信大伙至少已经掌握基本用法.在本文中,咱们继续探讨 CodeDom 方面的奥秘,这一次咱们聊聊命名空间. 在开始之前,老周 ...
- 【.net 深呼吸】细说CodeDom(2):表达式、语句
在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系. 在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下.严格上说,Emit并不是针对代 ...
- 【.net 深呼吸】细说CodeDom(9):动态编译
知道了如果构建代码文档,知道了如何生成代码,那么编译程序集就很简单了. CodeDomProvider 类提供了三个可以执行编译的方法: 1.CompileAssemblyFromSource——这个 ...
- 【.net 深呼吸】细说CodeDom(7):索引器
在开始正题之前,先补充一点前面的内容. 在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参 ...
- 【.net 深呼吸】细说CodeDom(6):方法参数
本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...
- 【.net 深呼吸】细说CodeDom(5):类型成员
前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...
- 【.net 深呼吸】细说CodeDom(4):类型定义
上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...
- 【.net 深呼吸】细说CodeDom(10):生成异常处理语句
写完这一篇,大概可以准备过年了,就算是这系列文章的收尾吧. 异常处理语句,就是常说的try...catch语句,有时候,也会带有finally子句.要生成异常处理语句,得用到CodeTryCatchF ...
随机推荐
- CoreCLR源码探索(一) Object是什么
.Net程序员们每天都在和Object在打交道 如果你问一个.Net程序员什么是Object,他可能会信誓旦旦的告诉你"Object还不简单吗,就是所有类型的基类" 这个答案是对的 ...
- 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?
今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...
- Appium移动自动化框架
引言:Appium 是一个移动端自动化测试开源工具,可以针对不同的平台用一套API来编写测试用例.本文对Appium自动化测试框架的功能进行了概括. 本文选自<软件自动化测试开发>. Ap ...
- video.js
1.github地址 2.常用API: class : video-js: video-js应用视频所需的风格.js功能,比如全屏和字幕. vjs-default-skin: vjs-default- ...
- CentOS 7配置LNMP开发环境及配置文件管理
安装并配置MySQL 5.6 从CentOS从7.x开始默认使用MariaDB.MariaDB完全兼容MySQL,包括API和命令行.但是很多时候我们还是会想要安装MySQL,所以不能直接通过yum命 ...
- Ngrok让你的本地Web应用暴露在公网上
1.Ngrok介绍 Ngrok是一个反向代理,通过在公共的端点和本地运行的Web服务器之间建立一个安全的通道.Ngrok可捕获和分析所有通道上的流量,便于后期分析和重放.简单来说,利用 Ngrok可以 ...
- 两个 viewports 的故事-第二部分
原文链接:A tale of two viewports — part two 译者:nzbin 在这个迷你系列中,我将解释 viewports 和各种重要元素的宽度是如何工作的,比如说 <ht ...
- 云瓣影音网站&&微信端(已开源)
随着该项目的发布到线上(小打小闹),即将又要开启另一段崭新的旅程.强迫自己停下来写写所学所得,个人认为总结和分享是一种很棒的学习方式.那让我们先来瞧瞧项目长的什么样.如果着急要源码的朋友,可以下拉到最 ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- maven 快照
大型应用软件一般由多个模块组成,一般它是多个团队开发同一个应用程序的不同模块,这是比较常见的场景.例如,一个团队正在对应用程序的应用程序,用户界面项目(app-ui.jar:1.0) 的前端进行开发, ...