`
java-mans
  • 浏览: 11444639 次
文章分类
社区版块
存档分类
最新评论

深入浅出.NET代码生成系列(4):定义类型

 
阅读更多

CodeTypeDeclaration类可以为我们定义类、结构、接口等。

1、BaseTypes描述要定义类型的基类型。

2、Members当然是定义类型的成员了,如属性、方法、事件等。

3、IsClass、IsEnum、IsInterface、IsStruct这几个就好理解了。

4、TypeAttributes就是对类型的特性描述了,比如public、static等。

5、TypeParameters,类型参数,用于泛型。

问题一:如何定义一个枚举?

首先,我们建一个控制台应用程序,很简单吧,我不多说了,此处省略36个字。

然后呢,代码如下,比较简单,所以我不注释了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;

namespace MyApp
{
    class Program
    {
        static void Main(string[] args)
        {
            CodeTypeDeclaration enum00 = new CodeTypeDeclaration("Abcdefg");
            enum00.IsEnum = true;

            enum00.Attributes = MemberAttributes.Public;

            CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
            provider.GenerateCodeFromType(enum00,
                                          Console.Out,
                                          new CodeGeneratorOptions());
            Console.ReadKey();
        }
    }
}


执行一下,看看效果。

问题二:如何生成类?

其实是一样的,把IsClass改为true就行了。

            CodeTypeDeclaration class001 = new CodeTypeDeclaration("ClassTest");
            class001.Attributes = MemberAttributes.Public;
            class001.IsClass = true;

            CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
            provider.GenerateCodeFromType(class001,Console.Out, new CodeGeneratorOptions());


生成接口、结构也差不多了,就是一个属性决定。

那么,大家可能有一个疑问,IsClass,IsInterface这些属性,如果我同时设置多个会怎么样呢?试试看。

代码一:

            CodeTypeDeclaration class001 = new CodeTypeDeclaration("ClassTest");
            class001.Attributes = MemberAttributes.Public;
            class001.IsClass = true;
            class001.IsInterface = true;

执行结果如图:


代码二:再加一行。

            CodeTypeDeclaration class001 = new CodeTypeDeclaration("ClassTest");
            class001.Attributes = MemberAttributes.Public;
            class001.IsClass = true;
            class001.IsInterface = true;
            class001.IsStruct = true;

执行效果如图:


这么看来,它是只认最后一次设置的值了,前面的都被忽略了。

问题三:委托如何定义?

委托是大小姐,身份特殊,所以有特殊待遇,吃饭也吃特供。故不使用CodeTypeDeclaration,而应当使用CodeTypeDelegate类,看看吧,身份再特殊的人都是人,所以,CodeTypeDelegate类其实是从CodeTypeDeclaration派生出来的。

委托这玩意儿我们知道,它其实和定义方法很像的,有返回值(设置ReturnType属性)和参数列表(向Parameters中添加元素)。来,看看下面的例子。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;

namespace MyApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            CodeTypeDelegate myDelegate = new CodeTypeDelegate("TestCallBack");
            myDelegate.Attributes = MemberAttributes.Public;
            myDelegate.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "num"));

            CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
            provider.GenerateCodeFromType(myDelegate, Console.Out, new CodeGeneratorOptions { BracingStyle = "C" });

            Console.ReadKey();
        }
    }
}


执行一下,看看结果如何。

默认是没有返回值的,咱们再来个有返回值的看看。

        static void Main(string[] args)
        {
            CodeTypeDelegate myDelegate = new CodeTypeDelegate("TestCallBack");
            myDelegate.Attributes = MemberAttributes.Public;
            myDelegate.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "a"));
            myDelegate.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string),"b"));
            myDelegate.ReturnType = new CodeTypeReference(typeof(bool));

            CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
            provider.GenerateCodeFromType(myDelegate, Console.Out, new CodeGeneratorOptions { BracingStyle = "C" });

            Console.ReadKey();
        }

看看结果。


问题四:如何为类定义成员?

亲,复习一下基础知识,类的成员有哪些?嗯,字段、属性、方法和事件,四大天王呢,是吧?好,现在开始对号入座,它们都对应着哪些类。

字段——CodeMemberField

属性——CodeMemberProperty

方法——CodeMemberMethod

事件——CodeMemberEvent

好了,入座完毕,开始看电影。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;

namespace MyApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            // 片首曲,定义一个类
            CodeTypeDeclaration Myclass = new CodeTypeDeclaration("HelloTest");
            // 设置相关参数
            Myclass.Attributes = MemberAttributes.Public;
            Myclass.IsClass = true;

            // 定义一个字段
            CodeMemberField mField = new CodeMemberField(typeof(int), "m_Num");
            // 将字段添加到类成员集合中
            Myclass.Members.Add(mField);

            // 定义一个属性
            CodeMemberProperty mProperty = new CodeMemberProperty();
            mProperty.Name = "Number";
            // 属性类型
            mProperty.Type = new CodeTypeReference(typeof(int));
            // get语句块
            mProperty.GetStatements.Add(new CodeMethodReturnStatement(
                    new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "m_Num")
                ));
            // set语句块
            mProperty.SetStatements.Add(new CodeAssignStatement(
                    new CodeMethodReferenceExpression(new CodeThisReferenceExpression(), "m_Num"),
                    new CodePropertySetValueReferenceExpression()
                ));
            // 将属性添加到类成员中
            Myclass.Members.Add(mProperty);

            // 定义一个方法
            CodeMemberMethod mMethod = new CodeMemberMethod();
            mMethod.Name = "DoWork";
            // 返回类型
            mMethod.ReturnType = new CodeTypeReference(typeof(string));
            // 公共方法
            mMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            // 方法体
            mMethod.Statements.Add(new CodeMethodReturnStatement(
                    new CodePrimitiveExpression("Hello Dog!")
                ));
            // 为方法添加注释
            mMethod.Comments.Add(new CodeCommentStatement("测试方法"));
            // 将方法添加到类成员中
            Myclass.Members.Add(mMethod);

            // 片尾曲,生成代码
            CodeDomProvider provider = CodeDomProvider.CreateProvider("cs");
            provider.GenerateCodeFromType(Myclass, Console.Out, new CodeGeneratorOptions { BracingStyle = "C" });

            Console.ReadKey();
        }
    }
}


再观看一下效果。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics