技术开发 频道

使用C# 2.0实现语言无关的代码生成器



四、属性的生成

 
    在数据表类中每个属性代表数据表的一个字段,名子就是字段名。这些属性和保存字段的全局变量一一对应。下面是具体的实现代码:
private void GenerateProperties() { String fieldname = "", fieldtype = ""; foreach (XmlNode xn in m_Xml.DocumentElement.ChildNodes) { fieldname = xn.Name; fieldtype = xn.Attributes["type"].Value; CodeMemberProperty property = new CodeMemberProperty(); property.Attributes = MemberAttributes.Public | MemberAttributes.Final; property.Name = fieldname; property.Type = new CodeTypeReference(fieldtype); property.HasGet = true; property.HasSet = true; CodeVariableReferenceExpression field = new CodeVariableReferenceExpression("m_" + fieldname); // 产生 return m_property CodeMethodReturnStatement propertyReturn = new CodeMethodReturnStatement(field); property.GetStatements.Add(propertyReturn); // 产生 m_property = value; CodeAssignStatement propertyAssignment = new CodeAssignStatement(field, new CodePropertySetValueReferenceExpression()); property.SetStatements.Add(propertyAssignment); m_Class.Members.Add(property); } }

    这些生成的属性是可读写的。这就需要将HasGet和HasSet两个属性设为true,然后分别将get和set方法中的语句分别加到GetStatements和SetStatements中。
构造函数的生成
    构造函数的主要工作是打开数据表。如果数据表不存在,就创建这个数据表文件。在编写代码之前,需要先定义三个全局变量。因为这三个全局变量在程序中会多次用到。它们的类型都是CodeVariableReferenceExpression。这个类型变量其实在生成源码中的作用就是对某一个变量的引用。具体的实现代码如下:
private CodeVariableReferenceExpression m_XmlFileExpression; private CodeVariableReferenceExpression m_XmlExpression; private CodeVariableReferenceExpression m_AddFlagExpression; private void InitVariants() { m_XmlFileExpression = new CodeVariableReferenceExpression("m_XmlFile"); m_XmlExpression = new CodeVariableReferenceExpression("m_xml"); m_AddFlagExpression = new CodeVariableReferenceExpression("m_AddFlag"); }

下面是生成构造函数的源代码:


Add和Save方法生成
Add方法只有一条语句,功能是将m_AddFlag设为true,以使数据表类处于加入状态。Save方法比较复杂。它的功能是当m_AddFlag为true时在数据表文件的最后加入一条记录,并保存。具体实现代码如下:
private void GenerateMethods() { CodeTypeReference voidReference = new CodeTypeReference("System.void"); //产生Add方法 CodeMemberMethod add = new CodeMemberMethod(); add.ReturnType = voidReference; add.Name = "add"; add.Attributes = MemberAttributes.Public | MemberAttributes.Final; CodeAssignStatement assignAddTrue = new CodeAssignStatement(m_AddFlagExpression, new CodePrimitiveExpression(true)); add.Statements.Add(assignAddTrue); m_Class.Members.Add(add); //产生Save方法 CodeMemberMethod save = new CodeMemberMethod(); save.ReturnType = voidReference; save.Name = "save"; save.Attributes = MemberAttributes.Public | MemberAttributes.Final; System.Collections.Generic.List<CodeStatement> ifStatements = new System.Collections.Generic.List<CodeStatement>(); //产生 "XmlNode xn = m_xml.CreateNode(XmlNodeType.Element, "item", "");" CodeVariableDeclarationStatement xmlNode = new CodeVariableDeclarationStatement("System.Xml.XmlNode", "xn"); CodeMethodInvokeExpression createNode = new CodeMethodInvokeExpression(m_XmlExpression, "CreateNode", new CodeExpression[] {new CodeVariableReferenceExpression("System.Xml.XmlNodeType.Element"), new CodePrimitiveExpression("item"), new CodePrimitiveExpression("") }); xmlNode.InitExpression = createNode; ifStatements.Add(xmlNode); //产生 "XmlAttribute xa = null; " CodeVariableDeclarationStatement xmlAttr = new CodeVariableDeclarationStatement("System.Xml.XmlAttribute", "xa"); xmlAttr.InitExpression = new CodePrimitiveExpression(null); ifStatements.Add(xmlAttr); //产生字段属性 CodeStatementCollection statements = new CodeStatementCollection(); foreach (XmlNode xn in m_Xml.DocumentElement.ChildNodes) { CodeMethodInvokeExpression createAttribute = new CodeMethodInvokeExpression(m_XmlExpression, "CreateAttribute", new CodePrimitiveExpression(xn.Name)); CodeAssignStatement assignxa = new CodeAssignStatement(new CodeVariableReferenceExpression("xa"), createAttribute); CodeMethodInvokeExpression invokeToString = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("m_" + xn.Name), "ToString"); CodeAssignStatement assignValue = new CodeAssignStatement(new CodeVariableReferenceExpression("xa.Value"), invokeToString); CodeMethodInvokeExpression invokeAppend = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("xn.Attributes"), "Append", new CodeVariableReferenceExpression("xa")); statements.Add(invokeAppend); ifStatements.Add(assignxa); ifStatements.Add(assignValue); ifStatements.Add(statements[0]); } // 产生 "m_xml.DocumentElement.AppendChild(xn);" CodeMethodInvokeExpression invokeAppendChild = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("m_xml.DocumentElement"), "AppendChild", new CodeVariableReferenceExpression("xn")); statements.Clear(); statements.Add(invokeAppendChild); ifStatements.Add(statements[0]); // 产生 "m_xml.Save(m_XmlFile);" CodeMethodInvokeExpression invokeSave = new CodeMethodInvokeExpression(m_XmlExpression, "Save", m_XmlFileExpression); statements.Clear(); statements.Add(invokeSave); ifStatements.Add(statements[0]); // 产生 "m_AddFlag = false;" CodeAssignStatement assignAddFalse = new CodeAssignStatement(m_AddFlagExpression, new CodePrimitiveExpression(false)); ifStatements.Add(assignAddFalse); // 产生if语句: "if (m_AddFlag)" CodeConditionStatement ifStatement = new CodeConditionStatement(m_AddFlagExpression, ifStatements.ToArray()); save.Statements.Add(ifStatement); m_Class.Members.Add(save); }

 

0
相关文章