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

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

在开始之前,先补充一下上一篇烂文的内容。在上一篇文章中,老周检讨了 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,下一次将介绍一下特性的定义。

 

posted @ 2016-12-27 17:48  东邪独孤  阅读(1657)  评论(1编辑  收藏  举报