本文老周就给大伙伴们介绍一下方法参数代码的生成。

在开始之前,先补充一下上一篇烂文的内容。在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作,后来发现是可以的。不过啊,MemberAttributes 枚举有些情况下不那么好弄,最典型的就是要生成抽象类的时候,反正老周试了很久,用MemberAttributes枚举不能顺利生成抽象类。

这时候,老周想到了 TypeAttributes,然后就试了一下。

            CodeTypeDeclaration t = new CodeTypeDeclaration("MyClass");
t.TypeAttributes = System.Reflection.TypeAttributes.Abstract; CodeMemberProperty pry = new CodeMemberProperty();
pry.Name = "A";
pry.Attributes = MemberAttributes.Abstract | MemberAttributes.Public;
pry.Type = new CodeTypeReference(typeof(string));
t.Members.Add(pry); CodeDomProvider p = CodeDomProvider.CreateProvider("cs");
p.GenerateCodeFromType(t, Console.Out, null);

把 TypeAttributes 属性设置为 Abstract ,就可以将类标识为抽象类。而抽象成员则可以将 Attributes 属性直接指定为抽象成员,比如上面例子中的A属性。

然后生成的代码如下图所示。

下面进入本文的要点——生成方法参数。

老周的习惯是,示例学习效率高。所以,我不多说理论的东西,来看例子。

            CodeMemberMethod m = new CodeMemberMethod();
m.Name = "SetData";
m.Attributes = MemberAttributes.Public | MemberAttributes.Final;
// 参数
CodeParameterDeclarationExpression p1 = new CodeParameterDeclarationExpression();
p1.Name = "name";
p1.Type = new CodeTypeReference(typeof(string));
m.Parameters.Add(p1);
CodeParameterDeclarationExpression p2 = new CodeParameterDeclarationExpression();
p2.Name = "city";
p2.Type = new CodeTypeReference(typeof(string));
m.Parameters.Add(p2);
CodeParameterDeclarationExpression p3 = new CodeParameterDeclarationExpression();
p3.Name = "phone";
p3.Type = new CodeTypeReference(typeof(int));
m.Parameters.Add(p3);
CodeCommentStatement cm = new CodeCommentStatement("方法体");
m.Statements.Add(cm); CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
provider.GenerateCodeFromMember(m, Console.Out, null);

别看这代码貌似有点长,其实就是声明一个方法,然后添加三个参数。参数的声明属于表达式,因此用到CodeParameterDeclarationExpression类,Type属性设置参数的类型。

示例代码中,CodeCommentStatement表示方法体中包含注释。

生成的方法如下图所示。

默认情况下,参数为输入参数,我们知道,还有两种方法参数——输出参数、引用传参。

CodeParameterDeclarationExpression 公开 Direction 属性,专门用于设置参数的方向,输入参数是默认值,因此可以不显式赋值,另外两个值就是Ref和Out。

下面代码将生成一个带有 out 参数的方法。

            CodeMemberMethod m3 = new CodeMemberMethod();
m3.Name = "MakeKey";
// 返回值
m3.ReturnType = new CodeTypeReference(typeof(bool));
// 输入参数
CodeParameterDeclarationExpression pi = new CodeParameterDeclarationExpression(typeof(int), "len");
m3.Parameters.Add(pi);
// 输出参数
CodeParameterDeclarationExpression po = new CodeParameterDeclarationExpression(typeof(byte[]), "res");
po.Direction = FieldDirection.Out; //重点
m3.Parameters.Add(po); Console.WriteLine("VB 代码:");
CodeDomProvider provider = CodeDomProvider.CreateProvider("vb");
provider.GenerateCodeFromMember(m3, Console.Out, null);
Console.WriteLine("\n\nC# 代码:");
provider = CodeDomProvider.CreateProvider("cs");
provider.GenerateCodeFromMember(m3, Console.Out, null);

要让参数变为输出参数,就要把 Direction 属性设置为 Out。

请看结果。

知道如何定义 out 参数,那ref参数就简单了,比如下面例子。

            // 定义类型
CodeTypeDeclaration dt = new CodeTypeDeclaration("MySocket");
// 方法成员
CodeMemberMethod mt = new CodeMemberMethod();
mt.Name = "ReadData";
mt.Attributes = MemberAttributes.Public;
// ref 参数
CodeParameterDeclarationExpression pr = new CodeParameterDeclarationExpression(typeof(System.Net.IPEndPoint), "endpoint");
pr.Direction = FieldDirection.Ref;
mt.Parameters.Add(pr);
dt.Members.Add(mt); CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
provider.GenerateCodeFromType(dt, Console.Out, null);

生成代码如下。

OK,今天的内容就讲完了,东西不多,也不难。下一篇文章,老周继续厚着脸皮和各位探讨 CodeDom,下一次将介绍一下特性的定义。

【.net 深呼吸】细说CodeDom(6):方法参数的更多相关文章

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

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

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

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

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

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

  4. Eclipse中自动提示的方法参数都是arg0,arg1的解决方法

    Eclipse中自动提示的方法参数都是arg0,arg1,就不能根据参数名来推断参数的含义,非常不方便. 解决方法:Preferences->Java->Installed JREs,发现 ...

  5. java中方法参数的一些总结(1)

    1.问题说明        在C++中,函数调用时有传值调用和传址调用两种方式,但在Java中只有传值调用一种方式.Java中的方法参数为那几种基本数据类型的情况跟C++中一样,传入的只是变量的拷贝. ...

  6. php课程---Windows.open()方法参数详解

    Window.open()方法参数详解 1, 最基本的弹出窗口代码   window.open('page.html'); 2, 经过设置后的弹出窗口   window.open('page.html ...

  7. Scala正则和抽取器:解析方法参数

    在<正则表达式基础知识>中概括了正则表达式的基础知识, 本文讲解如何使用正则表达式解析方法参数,从而可以根据 DAO 自动生成 Service. 在做 Java 项目时,常常要根据 DAO ...

  8. java方法参数

    Java程序设计语言总是采用值调用.也就是说,方法得到的是所有参数的一个拷贝,特别是方法不能修改传递给它的任何参数变量的内容. 基本类型参数 1)X被初始化为percent值的一个拷贝: 2)X被乘以 ...

  9. 新手容易混乱的String+和StringBuffer,以及Java的方法参数传递方式。

    之前在交流群里和猿友们讨论string+和stringbuffer哪个速度快以及Java的方法参数传递的问题,引起了群里猿友的小讨论.最终LZ得出的结果是string+没有stringbuffer快, ...

随机推荐

  1. 重温Http协议--请求报文和响应报文

    http协议是位于应用层的协议,我们在日常浏览网页比如在导航网站请求百度首页的时候,会先通过http协议把请求做一个类似于编码的工作,发送给百度的服务器,然后在百度服务器响应请求时把相应的内容再通过h ...

  2. html5 canvas常用api总结(二)--绘图API

    canvas可以绘制出很多奇妙的样式和美丽的效果,通过几个简单的api就可以在画布上呈现出千变万化的效果,还可以制作网页游戏,接下来就总结一下和绘图有关的API. 绘画的时候canvas相当于画布,而 ...

  3. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

  4. JAVA FreeMarker工具类

    FreeMarkerUtil.java package pers.kangxu.datautils.utils; import java.io.File; import java.io.StringW ...

  5. 《Note --- Unreal 4 --- Sample analyze --- StrategyGame(continue...)》

    ---------------------------------------------------------------------------------------------------- ...

  6. linux-centos在VM中的网络配置

    1.自动获取IP地址 虚拟机使用桥接模式,相当于连接到物理机的网络里,物理机网络有DHCP服务器自动分配IP地址. #dhclient 自动获取ip地址命令 #ifconfig 查询系统里网卡信息,i ...

  7. [PHP源码阅读]array_push和array_unshift函数

    在PHP中,在数组中添加元素也是一种很常用的操作,分别有在数组尾部和头部添加元素,看看PHP内部是如何实现数组插入的操作. 我在github有对PHP源码更详细的注解.感兴趣的可以围观一下,给个sta ...

  8. DIP原则、IoC以及DI

    一.DIP原则 高层模块不应该依赖于底层模块,二者都应该依赖于抽象. 抽象不应该依赖于细节,细节应该依赖于抽象. 该原则理解起来稍微有点抽象,我们可以将该原则通俗的理解为:"依赖于抽象&qu ...

  9. CSS currentColor 变量的使用

    CSS中存在一个神秘的变量,少有人知自然也不怎么为人所用.它就是crrentColor变量(或者说是CSS关键字,但我觉得称为变量好理解些). 初识 它是何物?具有怎样的功效?它从哪里来?带着这些疑问 ...

  10. C# 面向对象基础

    面向对象编程OOP(Object-Oriented Programming) 类和对象 类是对象的定义,对象是类的实现. [属性集信息] [类修饰符] class 类名 [:类基] //定义类的语法格 ...