• CodeDom系列二


    ---程序基本结构--符号三角形问题

    昨天一个同学叫我帮编写一个符号三角形的c代码,今天就把它改写成用CodeDom生成的c#代码。

        符号三角形:在一组字符串里(只有用空格分割的+或者-组成的字符串),在每次的相邻的两个符号比较,如果相同就在中间空格插入+,否则就插入-。一直运行到字符串里只有一个+或者-时停止,输出的字符串为符号三角形。

    由于是CodeDom些列,所以先介绍几个CodeDom表达式:

    1:CodeConditionStatement:判断语句即是if(condition){} else{},看最全的那个构造函数:

    public CodeConditionStatement(CodeExpression condition,//条件CodeStatement[] trueStatements,//为true的语句体CodeStatement[] falseStatements//为false语句体)
    2:CodeIterationStatement():表示 for 语句或语句块内的循环(使用测试表达式作为继续循环的条件):
    在codedom中没有提高while和dowhile但是For已经够用的
    public CodeIterationStatement(CodeStatement initStatement,//for初始化CodeExpression testExpression,//条件表达式CodeStatement incrementStatement,//for变化体,增或减CodeStatement[] statements//循环体)
    3:CodeBinaryOperatorExpression:表示一个表达式,该表达式包含在两个表达式间进行的二进制运算,
    public CodeBinaryOperatorExpression(CodeExpression left,//表达式左边CodeBinaryOperatorType op,//操作符CodeExpression right//表达式右边)
    4:CodeArrayIndexerExpression:表示对数组的索引的引用:
    public CodeArrayIndexerExpression(CodeExpression targetObject,//数组对象CodeExpression[] indices//下标)
    其他参见CodeDOM 快速参考:msdn.microsoft.com/zh-cn/library/f1dfsbhc(VS.80).aspx
    code:
    04 public CodeNamespace CreateNameSpace()
    05 {
    06 public CodeNamespace CreateNameSpace()
    07 {
    08 //Test
    09 CodeMemberMethod test = new CodeMemberMethod();
    10 test.Name = "Test";
    11 test.Attributes = MemberAttributes.Public | MemberAttributes.Final;
    12 test.Statements.Add(new CodeVariableDeclarationStatement(typeof(char[]), "ch",
    4 new CodeMethodInvokeExpression(new CodePrimitiveExpression("+ - + - + + - -"), "ToCharArray",
    4 new CodeExpression[] { })));
    5 test.Statements.Add(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression
    4 (new CodeThisReferenceExpression(), "FuHaoSanJiao"), new CodeExpression[] { new CodeVariableReferenceExpression("ch"),
    4 new CodePrimitiveExpression(0) }));
    5 test.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read"));
    6 //FuHaoSanJiao
    7 CodeMemberMethod fuHaoSanJiao = new CodeMemberMethod();
    8 fuHaoSanJiao.Name = "FuHaoSanJiao";
    9 fuHaoSanJiao.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(char[])),
    4 "ch"));
    5 fuHaoSanJiao.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "start"));
    6 fuHaoSanJiao.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),
    4 "WriteLine", new CodeExpression[] { new CodeObjectCreateExpression(typeof(string), new CodeArgumentReferenceExpression("ch")) }));
    5 fuHaoSanJiao.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(
    4 new CodeArgumentReferenceExpression("start"), CodeBinaryOperatorType.GreaterThanOrEqual,
    5 (new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(
    4 new CodeArgumentReferenceExpression("ch"),"Length"),
    5 CodeBinaryOperatorType.Divide ,new CodePrimitiveExpression(2)))),
    6 new CodeMethodReturnStatement()));
    7 CodeBinaryOperatorExpression condition=new CodeBinaryOperatorExpression(
    04 new CodeVariableReferenceExpression("i"),
    05 CodeBinaryOperatorType.LessThan,
    06 new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("ch"),"Length"),
    07 CodeBinaryOperatorType.Subtract ,new CodeArgumentReferenceExpression("start")), CodeBinaryOperatorType.Subtract,
    08 new CodePrimitiveExpression(1)));//for 条件
    09 CodeConditionStatement iterationBody=new CodeConditionStatement(new CodeBinaryOperatorExpression(
    10 new CodeArrayIndexerExpression(new CodeArgumentReferenceExpression("ch"),
    4 new CodeVariableReferenceExpression("i")),
    5 CodeBinaryOperatorType.IdentityEquality, new CodeArrayIndexerExpression(
    4 new CodeArgumentReferenceExpression("ch"),
    5 new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("i"),
    4 CodeBinaryOperatorType.Add,new CodePrimitiveExpression(2)))),
    5 new CodeAssignStatement(
    6 new CodeArrayIndexerExpression(new CodeArgumentReferenceExpression("ch"),
    4 new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("i"), CodeBinaryOperatorType.Add,
    4 new CodePrimitiveExpression(1))),
    5 new CodePrimitiveExpression('+')));
    6 iterationBody.FalseStatements.Add(new CodeAssignStatement(
    7 new CodeArrayIndexerExpression(new CodeArgumentReferenceExpression("ch"),
    4 new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("i"), CodeBinaryOperatorType.Add,
    4 new CodePrimitiveExpression(1))),
    5 new CodePrimitiveExpression('-')));
    6 CodeAssignStatement iteerationbody2 = new CodeAssignStatement(new CodeArrayIndexerExpression(
    4 new CodeArgumentReferenceExpression("ch"), new CodeVariableReferenceExpression("i")),
    5 new CodePrimitiveExpression(' '));
    6 fuHaoSanJiao.Statements.Add(new CodeIterationStatement(new CodeVariableDeclarationStatement(typeof(int),
    4 "i", new CodeArgumentReferenceExpression("start")), condition,
    5 new CodeAssignStatement(new CodeVariableReferenceExpression("i"),new CodeBinaryOperatorExpression(
    4 new CodeVariableReferenceExpression("i"), CodeBinaryOperatorType.Add,
    5 new CodePrimitiveExpression(2))), new CodeStatement[] { iterationBody, iteerationbody2 }));
    6 // ch[ch.Length - start - 1] = ' ';
    7 fuHaoSanJiao.Statements.Add(new CodeAssignStatement(
    8 new CodeArrayIndexerExpression(new CodeArgumentReferenceExpression("ch"),
    4 new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(
    4 new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("ch"), "Length"),
    5 CodeBinaryOperatorType.Subtract ,new CodeArgumentReferenceExpression("start")),
    4 CodeBinaryOperatorType.Subtract,
    5 new CodePrimitiveExpression(1))),new CodePrimitiveExpression(' ')));
    6 //  FuHaoSanJiao(ch, start + 1);
    7 fuHaoSanJiao.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(),
    4 "FuHaoSanJiao",new CodeArgumentReferenceExpression("ch")        ,
    5 new CodeBinaryOperatorExpression(new CodeArgumentReferenceExpression("start"),
    04 CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1))));
    05 CodeTypeDeclaration codeDomDemo2 = new CodeTypeDeclaration("CodeDomDemo2");
    06 codeDomDemo2.Members.Add(test);
    07 codeDomDemo2.Members.Add(fuHaoSanJiao);
    08 codeDomDemo2.Attributes = MemberAttributes.Public;
    09 codeDomDemo2.Comments.Add(new CodeCommentStatement("this code is from CodeDom!"));
    10 //codeDomDemo2.Members.AddRange();
    11 CodeNamespace nspace = new CodeNamespace("CodeDomDemo2");
    12 nspace.Imports.Add(new CodeNamespaceImport("System"));
    13 nspace.Types.Add(codeDomDemo2);
    14 return nspace;
    15 }
    16 }
    17 }

    输出代码为 :

    04 namespace CodeDomDemo2
    05 {
    06 using System;
    07 // this code is from CodeDom!
    08 public class CodeDomDemo2
    09 {
    10 public void Test()
    11 {
    12 char[] ch = "+ - + - + + - -".ToCharArray();
    13 this.FuHaoSanJiao(ch, 0);
    14 System.Console.Read();
    15 }
    16 private void FuHaoSanJiao(char[] ch, int start)
    17 {
    18 System.Console.WriteLine(new string(ch));
    19 if ((start
    20 >= (ch.Length / 2)))
    21 {
    22 return;
    23 }
    24 for (int i = start; (i
    25 < ((ch.Length - start)
    26 - 1)); i = (i + 2))
    27 {
    28 if ((ch[i] == ch[(i + 2)]))
    29 {
    30 ch[(i + 1)] = '+';
    31 } else
    32 {
    33 ch[(i + 1)] = '-';
    34 }
    35 ch[i] = ' ';
    36 }
    37 ch[((ch.Length - start)
    38 - 1)] = ' ';
    39 this.FuHaoSanJiao(ch, (start + 1));
    40 }
    41 }
    42 }

    代码下载Demo1,Demo2

    事件(event)定义和反射调用

        CodeDom提供了对事件的支持,以及我们可以用反射机制对CodeDom生成的事件进行注册,以及调用。本节程序很简单,先贴上我将用CodeDom生成的代码:

    04 namespace CodeDomDemo3
    05 {
    06 using System;
    07 public class CodeDomDemo3
    08 {
    09 public event System.EventHandler MyEvent;
    10 protected virtual void OnHandle(System.EventArgs e)
    11 {
    12 if ((this.MyEvent != null))
    13 {
    14 this.MyEvent(this, e);
    15 }
    16 }
    17 public void CallEvent()
    18 {
    19 this.OnHandle(EventArgs.Empty);
    20 }
    21 }
    22 }

    代码很简单哦,主要是看CodeDom的事件定义机制和反射调用CodeDom编译的类型方法事件。

    CodeDom代码为:

    04 using System;
    05 using System.Collections.Generic;
    06 using System.Linq;
    07 using System.Text;
    08 using System.CodeDom;
    09 namespace CodeDomDemo1
    10 {
    11 public class CodeDomDemo3
    12 {
    13 public CodeNamespace CreateCodeNamespcae()
    14 {
    15 CodeNamespace nspcae = new CodeNamespace("CodeDomDemo3");
    16 nspcae.Imports.Add(new CodeNamespaceImport("System"));
    17 nspcae.Types.Add(CrateClassType());
    18 return nspcae;
    19 }
    20 public CodeTypeDeclaration CrateClassType()
    21 {
    22 //field event
    23 CodeMemberEvent myevent = new CodeMemberEvent();
    24 myevent.Attributes = MemberAttributes.Public;
    25 myevent.Type = new CodeTypeReference(typeof(EventHandler));
    26 myevent.Name = "MyEvent";
    27 // event method OnHandle;
    28 CodeMemberMethod method = new CodeMemberMethod();
    29 method.Name = "OnHandle";
    30 method.Attributes = MemberAttributes.Family;
    31 method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(EventArgs)), "e"));
    32 method.Statements.Add(new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeEventReferenceExpression(
    4 new CodeThisReferenceExpression(),"MyEvent"),
    5 CodeBinaryOperatorType.IdentityInequality,new CodePrimitiveExpression(null)),
    6 new CodeExpressionStatement(new CodeDelegateInvokeExpression(new CodeEventReferenceExpression(
    04 new CodeThisReferenceExpression(),
    05 "MyEvent"), new CodeExpression[] { new CodeThisReferenceExpression(), new CodeArgumentReferenceExpression("e"),
    06 }))));
    07 CodeMemberMethod callEvent = new CodeMemberMethod();
    08 callEvent.Name = "CallEvent";
    09 callEvent.Attributes = MemberAttributes.Public | MemberAttributes.Final;
    10 callEvent.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "OnHandle", new CodeExpression[]
    04 {new CodePropertyReferenceExpression(new CodeTypeReferenceExpression("EventArgs"),"Empty") }));
    05 CodeTypeDeclaration myclass = new CodeTypeDeclaration("CodeDomDemo3");
    06 myclass.Attributes = MemberAttributes.Public;
    07 myclass.Members.AddRange(new CodeTypeMember[] { myevent, method, callEvent });
    08 return myclass;
    09 }
    10 }
    11 }
    4 1:主要注意委托的调用:
    public CodeDelegateInvokeExpression(CodeExpression targetObject,//事件的引用CodeExpression[] parameters//参数)
    2:事件的添加(+=):
    public CodeAttachEventStatement(CodeExpression targetObject,//目标对象string eventName,//事件名CodeExpression listener//监听者)
    3:事件的移除(-=):
    public CodeRemoveEventStatement(CodeExpression targetObject,//目标对象string eventName,//事件名CodeExpression listener//监听者)
       利用反射调用事件代码:
    4 Type t = result.CompiledAssembly.GetType("CodeDomDemo3.CodeDomDemo3");//获取类型
    5 object obj= Activator.CreateInstance(t);//创建实例
    6 t.GetEvent("MyEvent").AddEventHandler(obj, new EventHandler(pro.CallEvent));//添加事件
    7 t.GetMethod("CallEvent").Invoke(obj, null);//触发事件

    本示例代码下载:CodeDomDemo3

  • 相关阅读:
    OCP-1Z0-053-V13.02-638题
    OCP-1Z0-053-200题-60题-637
    OCP-1Z0-053-V13.02-637题
    OCP-1Z0-053-200题-47题-625
    OCP-1Z0-053-V13.02-625题
    OCP-1Z0-053-200题-42题-621
    OCP-1Z0-053-V13.02-621题
    OCP-1Z0-053-200题-41题-620
    OCP-1Z0-053-V13.02-620题
    OCP-1Z0-053-200题-37题-616
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/1763262.html
Copyright © 2020-2023  润新知