---程序基本结构--符号三角形问题
昨天一个同学叫我帮编写一个符号三角形的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() |
06 |
public CodeNamespace CreateNameSpace() |
09 |
CodeMemberMethod test = new CodeMemberMethod(); |
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")); |
7 |
CodeMemberMethod fuHaoSanJiao = new CodeMemberMethod(); |
8 |
fuHaoSanJiao.Name = "FuHaoSanJiao"; |
9 |
fuHaoSanJiao.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(char[])), |
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); |
输出代码为 :
04 |
namespace CodeDomDemo2 |
07 |
// this code is from CodeDom! |
08 |
public class CodeDomDemo2 |
12 |
char[] ch = "+ - + - + + - -".ToCharArray(); |
13 |
this.FuHaoSanJiao(ch, 0); |
14 |
System.Console.Read(); |
16 |
private void FuHaoSanJiao(char[] ch, int start) |
18 |
System.Console.WriteLine(new string(ch)); |
24 |
for (int i = start; (i |
25 |
< ((ch.Length - start) |
28 |
if ((ch[i] == ch[(i + 2)])) |
37 |
ch[((ch.Length - start) |
39 |
this.FuHaoSanJiao(ch, (start + 1)); |
代码下载Demo1,Demo2
事件(event)定义和反射调用
CodeDom提供了对事件的支持,以及我们可以用反射机制对CodeDom生成的事件进行注册,以及调用。本节程序很简单,先贴上我将用CodeDom生成的代码:
04 |
namespace CodeDomDemo3 |
07 |
public class CodeDomDemo3 |
09 |
public event System.EventHandler MyEvent; |
10 |
protected virtual void OnHandle(System.EventArgs e) |
12 |
if ((this.MyEvent != null)) |
14 |
this.MyEvent(this, e); |
17 |
public void CallEvent() |
19 |
this.OnHandle(EventArgs.Empty); |
代码很简单哦,主要是看CodeDom的事件定义机制和反射调用CodeDom编译的类型方法事件。
CodeDom代码为:
05 |
using System.Collections.Generic; |
09 |
namespace CodeDomDemo1 |
11 |
public class CodeDomDemo3 |
13 |
public CodeNamespace CreateCodeNamespcae() |
15 |
CodeNamespace nspcae = new CodeNamespace("CodeDomDemo3"); |
16 |
nspcae.Imports.Add(new CodeNamespaceImport("System")); |
17 |
nspcae.Types.Add(CrateClassType()); |
20 |
public CodeTypeDeclaration CrateClassType() |
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"), |
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 }); |
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