在上一篇文章中,老周介绍了表达式和语句,尽管老周没有把所有的内容都讲一遍,但相信大伙至少已经掌握基本用法。在本文中,咱们继续探讨 CodeDom 方面的奥秘,这一次咱们聊聊命名空间。

在开始之前,老周先厚着脸皮回答一位朋友的问题,有朋友问,我有一个代码文件,或者我直接把代码弄成文本,而不是生成的文档,那这些代码文本能编译吗? 当然可以了,后面老周会介绍的,如果你有兴趣,也可以自己研究研究,不难,其实蛮简单的。

在讲解过程中,可能老周会讲到重复的知识点,希望大家理解,因为很多知识不是孤立的,都会有联系,有时候说到一个东西,可能会牵扯到其他东西,老周一般都会废话一下,就是为了让大家更加明白,有时候难免会废话一下。

好,节目正式开播。

了解代码结构后,大伙一定知道,在一个程序集中,可以包含若干个命名空间,然后命名空间下面包含类型列表。要生成命名空间,可以使用 CodeNamespace 类,只要指定命名空间的名字就可以声明了。

下面代码生成一个名为 Common 的命名空间。

            CodeNamespace ns = new CodeNamespace("Common");
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(ns);
CodeDomProvider prd = CodeDomProvider.CreateProvider("cs");
prd.GenerateCodeFromCompileUnit(unit, Console.Out, null);

命名空间的容器是 CodeCompileUnit ,因此需要一个 CodeCompileUnit 实例来包装一下,它有一个 Namespaces 集合。生成的代码如下图所示。

在命名空间下,还可以添加类型,比如我加一个 Table 类。

            CodeNamespace ns = new CodeNamespace("Common");
CodeTypeDeclaration dcl = new CodeTypeDeclaration();
dcl.IsClass = true; // 它是类
dcl.Attributes = MemberAttributes.Public; // 而且是公共类
dcl.Name = "Table";
ns.Types.Add(dcl);
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(ns);

声明类型要用 CodeTypeDeclaration,IsClass明确它是一个类,Attributes可以设定成员的可访问性相关的属性。声明类型后,记得添加进命名空间的Types集合中。

生成的代码如下图所示。

这是有朋友会说,这大括号看得不太习惯,能不能让左大括号另起一行,行,可以用 CodeGeneratorOptions 来进行选项设置,比如这样。

            CodeDomProvider prd = CodeDomProvider.CreateProvider("cs");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
prd.GenerateCodeFromCompileUnit(unit, Console.Out, options);

BracingStyle属性有两个字符串的可用值,Block就是上面我们看到的那种,左大括号和声明代码位于同一位;如果为C,就是让左大括号另起一行。上面代码使用了C风格,左大括号会另起一行。

由于在组建代码文档时,不能用嵌套命名空间,所以可以分为多个命名空间处理。

            CodeNamespace ns = new CodeNamespace("SkinObjects");
CodeNamespace nssub = new CodeNamespace("SkinObjects.Models");
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(ns);
unit.Namespaces.Add(nssub);

于是生成的代码如下。

对代码文档而言,无所谓嵌套不嵌套的,都被看作一个命名空间。

你要是真的想要生成嵌套的命名空间,也可以用这种方法来折腾。

            string code = "namespace Test\n{\n" +
"\tnamespace Coms\n\t{\n\n\t}\n" +
"}";
CodeSnippetCompileUnit sunit = new CodeSnippetCompileUnit();
sunit.Value = code; CodeDomProvider prd = CodeDomProvider.CreateProvider("cs");
prd.GenerateCodeFromCompileUnit(sunit, Console.Out, null);

生成结果如下图所示。

CodeSnippetCompileUnit类的使用没有别的参数,只有一个字符串,它是把一整段代码的字符串直接用来生成,而不会去解析代码的结构。就算你这样:

            CodeDomProvider prd = CodeDomProvider.CreateProvider("vb");

哪怕把生成的代码语言改为VB,它最终生成的代码还是字符串里面指定的内容。说白了就是,CodeSnippetCompileUnit 直接把原义字符用于生成,而不考虑是什么语言什么语法。

就算你这么弄

            string code = "我是一个兵\n\n爱国爱人民。";
CodeSnippetCompileUnit sunit = new CodeSnippetCompileUnit();
sunit.Value = code;

它照样把字符串原封不动地生成,而不管是什么语言什么东东,反正只认字符串。

在一个命名空间中,经常会涉及到引入其他命名空间的事,C#中用using语句,VB中用Import语句。比如下面例子,声明的新命名空间里引入了三个其他的命名空间。

            CodeNamespace ns = new CodeNamespace("Dong");
ns.Imports.Add(new CodeNamespaceImport("System"));
ns.Imports.Add(new CodeNamespaceImport("System.IO"));
ns.Imports.Add(new CodeNamespaceImport("豆腐渣项目"));
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(ns);

CodeNamespace类有个Imports集合,其中每个CodeNamespaceImport对象用于指定引入的命名空间的名字。注意命名空间名字不要包含代码标点,比如C类的结束语中的分号,这个生成器会根据语言自动处理,你只需要写上命名空间的名字就行了。

如果是VB,就生成这样的代码。

如果是 C#,就会生成这样的代码。

看到了吧,后面的分号是自动加的,示语法而定。

如果是C++,会生成这样的代码。

注意,这里只是引入命名空间而已,不是引用的程序集,一定要区分清楚。如果你要引用某个程序集,应当在 CodeCompileUnit 类上设置,它有个ReferencedAssemblies集合,用一个字符串来表示引用的程序集。

对于GAC或.NET中的程序集,直接写名字就可以了,不用加上.dll,比如System。mscorelib不必引用,一般是默认添加的。如果要引用其他程序集,可以这样写。

            CodeCompileUnit unit = new CodeCompileUnit();
unit.ReferencedAssemblies.Add("System");
unit.ReferencedAssemblies.Add("System.ServiceModel");
unit.ReferencedAssemblies.Add("abcdef.dll");

好了,今天就只介绍了命名空间的生成,顺着这个层次,下一篇文章就讲一下类型的定义。

也许老周写得不好,大家就当娱乐节目看,有参考价值就好。

【.net 深呼吸】细说CodeDom(3):命名空间的更多相关文章

  1. 【.net 深呼吸】细说CodeDom(2):表达式、语句

    在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系. 在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下.严格上说,Emit并不是针对代 ...

  2. 【.net 深呼吸】细说CodeDom(5):类型成员

    前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...

  3. 【.net 深呼吸】细说CodeDom(1):结构大观

    CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...

  4. 【.net 深呼吸】细说CodeDom(9):动态编译

    知道了如果构建代码文档,知道了如何生成代码,那么编译程序集就很简单了. CodeDomProvider 类提供了三个可以执行编译的方法: 1.CompileAssemblyFromSource——这个 ...

  5. 【.net 深呼吸】细说CodeDom(8):分支与循环

    有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类.要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的.如果用.net的“反编译”工具 ...

  6. 【.net 深呼吸】细说CodeDom(7):索引器

    在开始正题之前,先补充一点前面的内容. 在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参 ...

  7. 【.net 深呼吸】细说CodeDom(6):方法参数

    本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...

  8. 【.net 深呼吸】细说CodeDom(4):类型定义

    上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...

  9. 【.net 深呼吸】细说CodeDom(10):生成异常处理语句

    写完这一篇,大概可以准备过年了,就算是这系列文章的收尾吧. 异常处理语句,就是常说的try...catch语句,有时候,也会带有finally子句.要生成异常处理语句,得用到CodeTryCatchF ...

随机推荐

  1. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  2. Javascript实用方法

    这篇我主要记录一些在工作中常用的.实用的方法. String trim 字符串方法中的trim主要用来去空格使用,很多时候,在后台做参数处理的时候,我们都会使用该方法,比如在获取用户输入的账户时 va ...

  3. submit text3常用快捷键

    在网上找了一些submit text的快捷键: Ctrl+D 选词 (反复按快捷键,即可继续向下同时选中下一个相同的文本进行同时编辑)Ctrl+G 跳转到相应的行Ctrl+J 合并行(已选择需要合并的 ...

  4. [干货来袭]MSSQL Server on Linux预览版安装教程(先帮大家踩坑)

    前言 昨天晚上微软爸爸开了全国开发者大会,会上的内容,我就不多说了,园子里面很多.. 我们唐总裁在今年曾今透漏过SQL Server love Linux,果不其然,这次开发者大会上就推出了MSSQL ...

  5. C# 程序中嵌入百度地图

    本例是对WinForm中使用百度地图的简要介绍.百度地图目前支持Android开发,IOS开发,Web开发,服务接口,具体可以参照'百度地图开放平台'. [动态加载百度地图]涉及到的知识点: WebB ...

  6. asp.net mvc 验证码

    效果图 验证码类 namespace QJW.VerifyCode { //用法: //public FileContentResult CreateValidate() //{ // Validat ...

  7. maven 中snapshot版本和release版本的区别

    maven中的仓库分为两种,snapshot快照仓库和release发布仓库.snapshot快照仓库用于保存开发过程中的不稳定版本,release正式仓库则是用来保存稳定的发行版本.定义一个组件/模 ...

  8. NodeJs支付宝移动支付签名及验签

    非常感谢 :http://www.jianshu.com/p/8513e995ff3a?utm_campaign=hugo&utm_medium=reader_share&utm_co ...

  9. Spring MVC重定向和转发以及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  10. linux常用命令(1)cd命令

    1 命令格式:cd [目录名]2 命令功能切换当前目录至dirName3 常用范例3.1 进入系统根目录cd /3.2 进入上级目录cd ..   或者 cd ..//3.3 进入当前用户主目录当前用 ...