Download
Download sourcecode
Download exe
Introduction
It's a tools to help you create the strong type collection class. However you can use SharpDevelop or CodeSmith to do it.
Background
This project is I used to study CodeDOM.
Using the code
file 1: the class to create the CollectionClass
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
using Microsoft.VJSharp;
namespace Twodays.Tools.CollectionMaker
{
public sealed class StrongTypeCollection
{
private StrongTypeCollection()
{
const string COPYRIGHT_INFO="TWODAYS CollectionMaker";
private static CodeCompileUnit Build(string nameSpace,string itemClassName,string collectionClassName)
{
CodeCompileUnit CompileUnit = new CodeCompileUnit();
#region 增加文件的整体信息
CodeNamespace codeNamespace = new CodeNamespace(nameSpace);
codeNamespace.Comments.Clear();
codeNamespace.Comments.Add(new CodeCommentStatement("-------------------------------------------------------------" ,false) );
codeNamespace.Comments.Add(new CodeCommentStatement("" ,false) );
codeNamespace.Comments.Add(new CodeCommentStatement(" Powered By: " + COPYRIGHT_INFO,false) );
codeNamespace.Comments.Add(new CodeCommentStatement(" Created By: " + System.Environment.UserName,false) );
codeNamespace.Comments.Add(new CodeCommentStatement(" Created Time: " + DateTime.Now.ToString(),false));
codeNamespace.Comments.Add(new CodeCommentStatement("" ,false) );
codeNamespace.Comments.Add(new CodeCommentStatement("-------------------------------------------------------------" ,false) );
codeNamespace.Imports.Add( new CodeNamespaceImport("System") );
codeNamespace.Imports.Add(new CodeNamespaceImport("System.Collections"));
CompileUnit.Namespaces.Add( codeNamespace );
#endregion
#region 增加集合类
CodeTypeDeclaration collectionClass = new CodeTypeDeclaration(collectionClassName);
#region 增加集合类的信息
collectionClass.BaseTypes.Add("CollectionBase");
collectionClass.Comments.Add(new CodeCommentStatement("<summary>",true));
collectionClass.Comments.Add(new CodeCommentStatement("<para>",true));
collectionClass.Comments.Add(new CodeCommentStatement("A collection that stores <see cref='"+itemClassName + "'/> objects.",true));
collectionClass.Comments.Add(new CodeCommentStatement("</para>",true));
collectionClass.Comments.Add(new CodeCommentStatement("</summary>",true));
collectionClass.Comments.Add(new CodeCommentStatement("<seealso cref='"+ collectionClassName +"'/>",true));
collectionClass.CustomAttributes.Add(new CodeAttributeDeclaration("Serializable"));
codeNamespace.Types.Add(collectionClass);
#endregion
#region 子项目数组的引用
CodeTypeReference itemArrayReference=new CodeTypeReference(itemClassName) ;
itemArrayReference.ArrayElementType =new CodeTypeReference(itemClassName) ;
itemArrayReference.ArrayRank=1;
#endregion
#region 构造函数
collectionClass.Members.Add(CreateConstructor(collectionClassName,"",""));
CodeConstructor cc1= CreateConstructor(collectionClassName," based on another <see cref='" + collectionClassName +"'/>","A <see cref='" + collectionClassName + "'/> from which the contents are copied");
cc1.Parameters.Add(new CodeParameterDeclarationExpression(collectionClassName,"val"));
CodeMethodInvokeExpression cc1_invoke=new CodeMethodInvokeExpression(new CodeThisReferenceExpression(),"AddRange",new CodeArgumentReferenceExpression("val"));
cc1.Statements.Add(cc1_invoke);
collectionClass.Members.Add(cc1);
CodeConstructor cc2=CreateConstructor(collectionClassName," containing any array of <see cref='"+itemClassName+"'/> objects","A array of <see cref='"+ itemClassName +"'/> objects with which to intialize the collection");
cc2.Parameters.Add(new CodeParameterDeclarationExpression(itemArrayReference,"val"));
CodeMethodInvokeExpression cc2_invoke=new CodeMethodInvokeExpression(new CodeThisReferenceExpression(),"AddRange",new CodeArgumentReferenceExpression("val"));
cc2.Statements.Add(cc2_invoke);
collectionClass.Members.Add(cc2);
#endregion
#region 索引器
CodeMemberProperty indexer = new CodeMemberProperty();
indexer.Attributes = MemberAttributes.Final | MemberAttributes.Public;
indexer.Name = "Item";
indexer.Type = new CodeTypeReference(itemClassName);
indexer.Parameters.Add(new CodeParameterDeclarationExpression(typeof (int), "index"));
indexer.HasGet = true;
indexer.HasSet = true;
indexer.GetStatements.Add(
new CodeMethodReturnStatement(
new CodeCastExpression(
itemClassName,
new CodeIndexerExpression(
new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), "List"),
new CodeExpression[] {new CodeArgumentReferenceExpression("index")}
)
)
)
);
indexer.SetStatements.Add(
new CodeAssignStatement(
new CodeIndexerExpression(
new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(), "List"),
new CodeExpression[] {new CodeArgumentReferenceExpression("index")}
),
new CodeArgumentReferenceExpression("value")
)
);
indexer.Comments.Add(new CodeCommentStatement("<summary>",true));
indexer.Comments.Add(new CodeCommentStatement("<para>Represents the entry at the specified index of the <see cref='" +itemClassName + "'/>.</para>",true));
indexer.Comments.Add(new CodeCommentStatement("</summary>",true));
indexer.Comments.Add(new CodeCommentStatement("<param name='index'><para>The zero-based index of the entry to locate in the collection.</para></param>",true));
indexer.Comments.Add(new CodeCommentStatement("<val>",true));
indexer.Comments.Add(new CodeCommentStatement(" <para> The entry at the specified index of the collection.</para>",true));
indexer.Comments.Add(new CodeCommentStatement("</val>",true));
indexer.Comments.Add(new CodeCommentStatement("<exception cref='System.ArgumentOutOfRangeException'><paramref name='index'/> is outside the valid range of indexes for the collection.</exception>",true));
collectionClass.Members.Add(indexer);
#endregion
#region Add方法
CodeMemberMethod add=new CodeMemberMethod() ;
add.Attributes=MemberAttributes.Final |MemberAttributes.Public;
add.ReturnType=new CodeTypeReference(typeof(int)) ;
add.Name="Add";
add.Parameters.Add(new CodeParameterDeclarationExpression(itemClassName ,"val")) ;
add.Statements.Add(
new CodeMethodReturnStatement(
new CodeMethodInvokeExpression(
new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(),"List"),"Add",new CodeArgumentReferenceExpression("val")
)
)
);
add.Comments.Add(new CodeCommentStatement("<summary>",true));
add.Comments.Add(new CodeCommentStatement(" <para>Adds a <see cref='" + itemClassName + "'/> with the specified val to the",true));
add.Comments.Add(new CodeCommentStatement(" <see cref='" + collectionClassName + "'/> .</para>",true));
add.Comments.Add(new CodeCommentStatement("</summary>",true));
add.Comments.Add(new CodeCommentStatement("<param name='val'>The <see cref='" + itemClassName + "'/> to add.</param>",true));
add.Comments.Add(new CodeCommentStatement("<returns>",true));
add.Comments.Add(new CodeCommentStatement(" <para>The index at which the new element was inserted.</para>",true));
add.Comments.Add(new CodeCommentStatement("</returns>",true));
add.Comments.Add(new CodeCommentStatement("<seealso cref='" + collectionClassName + ".AddRange'/>",true));
collectionClass.Members.Add(add);
#endregion
#region AddRange方法
CodeMemberMethod addrange1=new CodeMemberMethod() ;
addrange1.Attributes=MemberAttributes.Final |MemberAttributes.Public;
addrange1.Name="AddRange";
addrange1.Parameters.Add(new CodeParameterDeclarationExpression(itemArrayReference,"val")) ;
CodeIterationStatement forLoop ;
forLoop = CreateForLoop("Length");
addrange1.Statements.Add(new CodeVariableDeclarationStatement(typeof(int),"i") ) ;
addrange1.Statements.Add(forLoop);
addrange1.Comments.Add(new CodeCommentStatement("<summary>",true));
addrange1.Comments.Add(new CodeCommentStatement("<para>Copies the elements of an array to the end of the <see cref='" + collectionClassName + "'/>.</para>",true));
addrange1.Comments.Add(new CodeCommentStatement("</summary>",true));
addrange1.Comments.Add(new CodeCommentStatement("<param name='val'>",true));
addrange1.Comments.Add(new CodeCommentStatement(" An array of type <see cref='" + itemClassName + "'/> containing the objects to add to the collection.",true));
addrange1.Comments.Add(new CodeCommentStatement("</param>",true));
addrange1.Comments.Add(new CodeCommentStatement("<returns>",true));
addrange1.Comments.Add(new CodeCommentStatement(" <para>None.</para>",true));
addrange1.Comments.Add(new CodeCommentStatement("</returns>",true));
addrange1.Comments.Add(new CodeCommentStatement("<seealso cref='" + collectionClassName + ".Add'/>",true));
collectionClass.Members.Add(addrange1);
#endregion
#region AddRange方法
CodeMemberMethod addrange2=new CodeMemberMethod() ;
addrange2.Attributes=MemberAttributes.Final |MemberAttributes.Public;
addrange2.Name="AddRange";
addrange2.Parameters.Add(new CodeParameterDeclarationExpression(collectionClassName,"val")) ;
addrange2.Statements.Add(new CodeVariableDeclarationStatement(typeof(int),"i") ) ;
forLoop=CreateForLoop("Count");
addrange2.Statements.Add(forLoop);
addrange2.Comments.Add(new CodeCommentStatement("<summary>",true));
addrange2.Comments.Add(new CodeCommentStatement(" <para>",true));
addrange2.Comments.Add(new CodeCommentStatement(" Adds the contents of another <see cref='" + collectionClassName + "'/> to the end of the collection.",true));
addrange2.Comments.Add(new CodeCommentStatement(" </para>",true));
addrange2.Comments.Add(new CodeCommentStatement("</summary>",true));
addrange2.Comments.Add(new CodeCommentStatement("<param name='val'>",true));
addrange2.Comments.Add(new CodeCommentStatement(" A <see cref='" + collectionClassName + "'/> containing the objects to add to the collection.",true));
addrange2.Comments.Add(new CodeCommentStatement("</param>",true));
addrange2.Comments.Add(new CodeCommentStatement("<returns>",true));
addrange2.Comments.Add(new CodeCommentStatement(" <para>None.</para>",true));
addrange2.Comments.Add(new CodeCommentStatement("</returns>",true));
addrange2.Comments.Add(new CodeCommentStatement("<seealso cref='" + collectionClassName + ".Add'/>",true));
collectionClass.Members.Add(addrange2);
#endregion
#region Contains方法
CodeMemberMethod contains=new CodeMemberMethod() ;
contains.Name ="Contains";
contains.ReturnType=new CodeTypeReference(typeof(bool));
contains.Attributes=MemberAttributes.Final| MemberAttributes.Public;
contains.Parameters.Add(new CodeParameterDeclarationExpression(itemClassName,"val"));
contains.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(),"List"),"Contains",new CodeArgumentReferenceExpression("val"))));
contains.Comments.Add(new CodeCommentStatement("<summary>",true) );
contains.Comments.Add(new CodeCommentStatement("<para>Gets a val indicating whether the",true) );
contains.Comments.Add(new CodeCommentStatement(" <see cref='"+ collectionClassName + "'/> contains the specified <see cref='" + itemClassName + "'/>.</para>",true) );
contains.Comments.Add(new CodeCommentStatement("</summary>",true) );
contains.Comments.Add(new CodeCommentStatement("<param name='val'>The <see cref='" + itemClassName + "'/> to locate.</param>",true) );
contains.Comments.Add(new CodeCommentStatement("<returns>",true) );
contains.Comments.Add(new CodeCommentStatement("<para><see langword='true'/> if the <see cref='" + itemClassName + "'/> is contained in the collection; ",true) );
contains.Comments.Add(new CodeCommentStatement(" otherwise, <see langword='false'/>.</para>",true) );
contains.Comments.Add(new CodeCommentStatement("</returns>",true) );
contains.Comments.Add(new CodeCommentStatement("<seealso cref='" + collectionClassName+ ".IndexOf'/>",true) );
collectionClass.Members.Add(contains);
#endregion
#region CopyTo方法
CodeMemberMethod copyto=new CodeMemberMethod() ;
copyto.Name="CopyTo";
copyto.Attributes=MemberAttributes.Final | MemberAttributes.Public;
copyto.Parameters.Add(new CodeParameterDeclarationExpression(itemArrayReference,"array")) ;
copyto.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int),"index") ) ;
copyto.Statements.Add((new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(),"List"),"CopyTo",new CodeExpression[]{new CodeArgumentReferenceExpression("array"),new CodeArgumentReferenceExpression("index") }) ) ) ;
copyto.Comments.Add(new CodeCommentStatement("<summary>",true));
copyto.Comments.Add(new CodeCommentStatement("<para>Copies the <see cref='" + collectionClassName + "'/> values to a one-dimensional <see cref='System.Array'/> instance at the ",true));
copyto.Comments.Add(new CodeCommentStatement(" specified index.</para>",true));
copyto.Comments.Add(new CodeCommentStatement("</summary>",true));
copyto.Comments.Add(new CodeCommentStatement("<param name='array'><para>The one-dimensional <see cref='System.Array'/> that is the destination of the values copied from <see cref='" + collectionClassName + "'/> .</para></param>",true));
copyto.Comments.Add(new CodeCommentStatement("<param name='index'>The index in <paramref name='array'/> where copying begins.</param>",true));
copyto.Comments.Add(new CodeCommentStatement("<returns>",true));
copyto.Comments.Add(new CodeCommentStatement(" <para>None.</para>",true));
copyto.Comments.Add(new CodeCommentStatement("</returns>",true));
copyto.Comments.Add(new CodeCommentStatement("<exception cref='System.ArgumentException'><para><paramref name='array'/> is multidimensional.</para> <para>-or-</para> <para>The number of elements in the <see cref='"+ collectionClassName +"'/> is greater than the available space between <paramref name='arrayIndex'/> and the end of <paramref name='array'/>.</para></exception>",true));
copyto.Comments.Add(new CodeCommentStatement("<exception cref='System.ArgumentNullException'><paramref name='array'/> is <see langword='null'/>. </exception>",true));
copyto.Comments.Add(new CodeCommentStatement("<exception cref='System.ArgumentOutOfRangeException'><paramref name='arrayIndex'/> is less than <paramref name='array'/>'s lowbound. </exception>",true));
copyto.Comments.Add(new CodeCommentStatement("<seealso cref='System.Array'/>",true));
collectionClass.Members.Add(copyto);
#endregion
#region IndexOf方法
CodeMemberMethod indexof=new CodeMemberMethod() ;
indexof.Name ="IndexOf";
indexof.Attributes=MemberAttributes.Final| MemberAttributes.Public;
indexof.ReturnType =new CodeTypeReference(typeof(int)) ;
indexof.Parameters.Add(new CodeParameterDeclarationExpression(itemClassName,"val") ) ;
indexof.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(),"List"),"IndexOf",new CodeArgumentReferenceExpression("val")) ) );
indexof.Comments.Add(new CodeCommentStatement("<summary>",true));
indexof.Comments.Add(new CodeCommentStatement(" <para>Returns the index of a <see cref='" +itemClassName+ "'/> in ",true));
indexof.Comments.Add(new CodeCommentStatement(" the <see cref='" + collectionClassName + "'/> .</para>",true));
indexof.Comments.Add(new CodeCommentStatement("</summary>",true));
indexof.Comments.Add(new CodeCommentStatement("<param name='val'>The <see cref='" + itemClassName + "'/> to locate.</param>",true));
indexof.Comments.Add(new CodeCommentStatement("<returns>",true));
indexof.Comments.Add(new CodeCommentStatement("<para>The index of the <see cref='" + itemClassName + "'/> of <paramref name='val'/> in the ",true));
indexof.Comments.Add(new CodeCommentStatement("<see cref='" + collectionClassName + "'/>, if found; otherwise, -1.</para>",true));
indexof.Comments.Add(new CodeCommentStatement("</returns>",true));
indexof.Comments.Add(new CodeCommentStatement("<seealso cref='" + collectionClassName + ".Contains'/>",true));
collectionClass.Members.Add(indexof) ;
#endregion
#region Insert方法
CodeMemberMethod insert=new CodeMemberMethod() ;
insert.Name ="Insert";
insert.Attributes =MemberAttributes.Final| MemberAttributes.Public;
insert.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int),"index") );
insert.Parameters.Add(new CodeParameterDeclarationExpression(itemClassName,"val") ) ;
insert.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(),"List"),"Insert",new CodeExpression[]{new CodeArgumentReferenceExpression("index"),new CodeArgumentReferenceExpression("val")} ) );
insert.Comments.Add(new CodeCommentStatement("<summary>",true));
insert.Comments.Add(new CodeCommentStatement("<para>Inserts a <see cref='" + itemClassName + "'/> into the <see cref='" + collectionClassName + "'/> at the specified index.</para>",true));
insert.Comments.Add(new CodeCommentStatement("</summary>",true));
insert.Comments.Add(new CodeCommentStatement("<param name='index'>The zero-based index where <paramref name='val'/> should be inserted.</param>",true));
insert.Comments.Add(new CodeCommentStatement("<param name=' val'>The <see cref='" + itemClassName + "'/> to insert.</param>",true));
insert.Comments.Add(new CodeCommentStatement("<returns><para>None.</para></returns>",true));
insert.Comments.Add(new CodeCommentStatement("<seealso cref='" + collectionClassName + ".Add'/>",true));
collectionClass.Members.Add(insert);
#endregion
#region GetEnumerator方法
CodeMemberMethod getenumerator=new CodeMemberMethod() ;
getenumerator.Name ="GetEnumerator";
getenumerator.Attributes =MemberAttributes.New | MemberAttributes.Public | MemberAttributes.Final;
getenumerator.ReturnType =new CodeTypeReference(itemClassName + "Enumerator") ;
getenumerator.Statements.Add(new CodeMethodReturnStatement(new CodeObjectCreateExpression(itemClassName + "Enumerator",new CodeExpression[]{new CodeThisReferenceExpression()} ) ) );
getenumerator.Comments.Add(new CodeCommentStatement("<summary>",true) ) ;
getenumerator.Comments.Add(new CodeCommentStatement(" <para>Returns an enumerator that can iterate through ",true) ) ;
getenumerator.Comments.Add(new CodeCommentStatement(" the <see cref='" + collectionClassName+ "'/> .</para>",true) ) ;
getenumerator.Comments.Add(new CodeCommentStatement("</summary>",true) ) ;
getenumerator.Comments.Add(new CodeCommentStatement("<returns><para>None.</para></returns>",true) ) ;
getenumerator.Comments.Add(new CodeCommentStatement("<seealso cref='System.Collections.IEnumerator'/>",true) ) ;
collectionClass.Members.Add(getenumerator) ;
#endregion
#region Remove方法
CodeMemberMethod remove =new CodeMemberMethod() ;
remove.Name ="Remove";
remove.Attributes =MemberAttributes.Final| MemberAttributes.Public;
remove.Parameters.Add(new CodeParameterDeclarationExpression(itemClassName,"val") ) ;
remove.Statements.Add(new CodeMethodInvokeExpression(new CodePropertyReferenceExpression(new CodeBaseReferenceExpression(),"List") ,"Remove",new CodeExpression[]{new CodeArgumentReferenceExpression("val") } ) ) ;
remove.Comments.Add(new CodeCommentStatement("<summary>",true) ) ;
remove.Comments.Add(new CodeCommentStatement(" <para> Removes a specific <see cref='"+ itemClassName +"'/> from the ",true) ) ;
remove.Comments.Add(new CodeCommentStatement(" <see cref='" + collectionClassName + "'/> .</para>",true) ) ;
remove.Comments.Add(new CodeCommentStatement("</summary>",true) ) ;
remove.Comments.Add(new CodeCommentStatement("<param name='val'>The <see cref='" +itemClassName+ "'/> to remove from the <see cref='" + collectionClassName +"'/> .</param>",true) ) ;
remove.Comments.Add(new CodeCommentStatement("<returns><para>None.</para></returns>",true) ) ;
remove.Comments.Add(new CodeCommentStatement("<exception cref='System.ArgumentException'><paramref name='val'/> is not found in the Collection. </exception>",true) ) ;
collectionClass.Members.Add(remove);
#endregion
collectionClass.Members.Add(GetEnumerator(itemClassName,collectionClassName));
#endregion
return CompileUnit;
}
private static CodeTypeDeclaration GetEnumerator(string itemClassName,string collectionClassName)
{
#region 枚举器类
CodeTypeDeclaration enumeratorClass = new CodeTypeDeclaration(itemClassName + "Enumerator");
enumeratorClass.BaseTypes.Add("IEnumerator");
enumeratorClass.Comments.Add(new CodeCommentStatement("<summary>",true) ) ;
enumeratorClass.Comments.Add(new CodeCommentStatement(" Enumerator of the <see cref='" +collectionClassName+ "'/>." ,true) ) ;
enumeratorClass.Comments.Add(new CodeCommentStatement("</summary>",true) ) ;
#endregion
#region 私有变量
CodeMemberField baseEnumerator=new CodeMemberField("IEnumerator","baseEnumerator") ;
CodeMemberField temp=new CodeMemberField("IEnumerable","temp") ;
enumeratorClass.Members.Add(baseEnumerator) ;
enumeratorClass.Members.Add(temp) ;
#endregion
#region 构造函数
CodeConstructor constructor=new CodeConstructor() ;
constructor.Attributes =MemberAttributes.Public;
constructor.Parameters.Add(new CodeParameterDeclarationExpression(collectionClassName,"mappings" ) ) ;
constructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(),"temp"),new CodeCastExpression("IEnumerable",new CodeArgumentReferenceExpression("mappings"))) ) ;
constructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeThisReferenceExpression(),"baseEnumerator"),new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"temp"),"GetEnumerator",new CodeExpression[]{} ) ) ) ;
constructor.Comments.Add(new CodeCommentStatement("<summary>",true) ) ;
constructor.Comments.Add(new CodeCommentStatement("The Constructor of" + enumeratorClass.Name,true) ) ;
constructor.Comments.Add(new CodeCommentStatement("</summary>",true) ) ;
constructor.Comments.Add(new CodeCommentStatement("<param name='mappings'> The <see cref='" + collectionClassName + "'/> containing the objects to initialize the collection.</param>",true) ) ;
enumeratorClass.Members.Add(constructor) ;
#endregion
#region Current属性
CodeMemberProperty current= new CodeMemberProperty() ;
current.Type =new CodeTypeReference(itemClassName) ;
current.Name ="Current";
current.HasGet =true;
current.HasSet=false;
current.Attributes =MemberAttributes.Public | MemberAttributes.Final;
current.GetStatements.Add(new CodeMethodReturnStatement(new CodeCastExpression(itemClassName,new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"baseEnumerator"),"Current") ) ) );
current.Comments.Add(new CodeCommentStatement("<summary>",true) ) ;
current.Comments.Add(new CodeCommentStatement("Get current <see cref='" + itemClassName + "'/>",true) ) ;
current.Comments.Add(new CodeCommentStatement("</summary>",true) ) ;
enumeratorClass.Members.Add(current);
#endregion
#region 实现IEnumerator的Current属性
CodeMemberProperty iCurrent=new CodeMemberProperty() ;
iCurrent.Name ="IEnumerator.Current";
iCurrent.Type =new CodeTypeReference(typeof(object)) ;
iCurrent.Attributes=MemberAttributes.Final;
iCurrent.HasGet =true;
iCurrent.HasSet=false;
iCurrent.GetStatements.Add(new CodeMethodReturnStatement(new CodePropertyReferenceExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"baseEnumerator") ,"Current") ) ) ;
enumeratorClass.Members.Add(iCurrent) ;
#endregion
#region MoveNext方法
CodeMemberMethod movenext=new CodeMemberMethod() ;
movenext.Name ="MoveNext";
movenext.ReturnType =new CodeTypeReference(typeof(bool)) ;
movenext.Attributes =MemberAttributes.Final | MemberAttributes.Public ;
movenext.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"baseEnumerator"),"MoveNext",new CodeExpression[]{} ) ));
movenext.Comments.Add(new CodeCommentStatement("<summary>",true) ) ;
movenext.Comments.Add(new CodeCommentStatement(" Set the current <see cref='" + itemClassName + "'/> to the next.",true) ) ;
movenext.Comments.Add(new CodeCommentStatement("</summary>",true) ) ;
movenext.Comments.Add(new CodeCommentStatement("<returns> If operate success return True else Flase.</returns>",true) ) ;
enumeratorClass.Members.Add(movenext) ;
#endregion
#region 实现IEnumerator的MoveNext方法
CodeMemberMethod iMoveNext=new CodeMemberMethod() ;
iMoveNext.Name ="IEnumerator.MoveNext";
iMoveNext.ReturnType =new CodeTypeReference(typeof(bool)) ;
iMoveNext.Attributes =MemberAttributes.Final;
iMoveNext.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"baseEnumerator"),"MoveNext",new CodeExpression[]{} ) ));
enumeratorClass.Members.Add(iMoveNext) ;
#endregion
#region Reset方法
CodeMemberMethod reset=new CodeMemberMethod() ;
reset.Name ="Reset";
reset.Attributes =MemberAttributes.Final | MemberAttributes.Public ;
reset.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"baseEnumerator"),"Reset",new CodeExpression[]{} ) ) ;
reset.Comments.Add(new CodeCommentStatement("<summary>",true) ) ;
reset.Comments.Add(new CodeCommentStatement(" Reset current point of the IEnumerator.",true) ) ;
reset.Comments.Add(new CodeCommentStatement("</summary>",true) ) ;
enumeratorClass.Members.Add(reset) ;
#endregion
#region 实现IEnumerator的Reset方法
CodeMemberMethod iReset=new CodeMemberMethod() ;
iReset.Name ="IEnumerator.Reset";
iReset.Attributes =MemberAttributes.Final;
iReset.Statements.Add(new CodeMethodInvokeExpression(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(),"baseEnumerator"),"Reset",new CodeExpression[]{} ) ) ;
enumeratorClass.Members.Add(iReset) ;
#endregion
return enumeratorClass;
}
private static CodeIterationStatement CreateForLoop(string valPropertyName)
{
CodeIterationStatement forLoop;
forLoop= new CodeIterationStatement(
new CodeAssignStatement( new CodeVariableReferenceExpression("i"), new CodePrimitiveExpression(0) ),
new CodeBinaryOperatorExpression( new CodeVariableReferenceExpression("i"),
CodeBinaryOperatorType.LessThan, new CodePropertyReferenceExpression(new CodeArgumentReferenceExpression("val"),valPropertyName)),
new CodeAssignStatement( new CodeVariableReferenceExpression("i"), new CodeBinaryOperatorExpression(
new CodeVariableReferenceExpression("i"), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1) )),
new CodeStatement[]{ new CodeExpressionStatement( new CodeMethodInvokeExpression(new CodeThisReferenceExpression(),"Add",new CodeIndexerExpression(new CodeArgumentReferenceExpression("val"),new CodeVariableReferenceExpression("i")) ) ) });
return forLoop;
}
private static CodeConstructor CreateConstructor(string collectionClassName, string paraEnd,string paramInfo)
{
CodeConstructor cc =new CodeConstructor() ;
cc.Attributes =MemberAttributes.Public ;
cc.Comments.Add(new CodeCommentStatement("<summary>",true));
cc.Comments.Add(new CodeCommentStatement(" <para>",true));
cc.Comments.Add(new CodeCommentStatement(" Initializes a new instance of <see cref='" + collectionClassName + "'/>" + paraEnd + ".",true));
cc.Comments.Add(new CodeCommentStatement(" </para>",true));
cc.Comments.Add(new CodeCommentStatement("</summary>",true));
if(paramInfo.Length>0)
{
cc.Comments.Add(new CodeCommentStatement("<param name='val'>",true));
cc.Comments.Add(new CodeCommentStatement(" "+paramInfo,true));
cc.Comments.Add(new CodeCommentStatement("</param>",true));
}
return cc;
}
public static void Make(string itemTypeName,string nameSpace,string collectionClassName,CodeType codeType,TextWriter textWriter)
{
CodeDomProvider provider;
switch(codeType)
{
case CodeType.CSharp:
provider=new CSharpCodeProvider();
break;
case CodeType.VB:
provider=new VBCodeProvider();
break;
case CodeType.JSharp:
provider=new VJSharpCodeProvider();
break;
default:
provider=new CSharpCodeProvider();
break;
}
ICodeGenerator gen=provider.CreateGenerator();
IndentedTextWriter tw = new IndentedTextWriter(textWriter, " ");
CodeGeneratorOptions cgo=new CodeGeneratorOptions() ;
cgo.BlankLinesBetweenMembers =true;
cgo.BracingStyle="C";
cgo.ElseOnClosing=true;
gen.GenerateCodeFromCompileUnit(Build(nameSpace,itemTypeName,collectionClassName), tw, cgo);
tw.Close();
}
public static void Make(string itemTypeName,string nameSpace,string collectionClassName,CodeType codeType,string fileName)
{
TextWriter tw= new StreamWriter(fileName, false);
Make(itemTypeName,nameSpace,collectionClassName,codeType,tw);
tw.Close();
}
public static string Make(string itemTypeName,string nameSpace,string collectionClassName,CodeType codeType)
{
string tempfile=System.IO.Path.GetTempFileName();
StrongTypeCollection.Make(itemTypeName ,nameSpace , collectionClassName ,codeType,tempfile) ;
string Result="";
using (StreamReader sr = new StreamReader(tempfile))
{
for(int i=0;i<9;i++)
sr.ReadLine();
Result =sr.ReadToEnd();
}
System.IO.File.Delete(tempfile) ;
return Result;
}
public enum CodeType
{
CSharp,
VB,
JSharp
}
}
}
file 2: the UI
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
namespace Twodays.Tools.CollectionMaker
{
public class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Panel TopPanel;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox ItemClassName;
private System.Windows.Forms.TextBox CollectionClassName;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox NameSpace;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.ComboBox LanguageType;
private System.Windows.Forms.Button Make;
private System.Windows.Forms.TextBox Code;
private System.ComponentModel.Container components = null;
public MainForm()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗体设计器生成的代码
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(MainForm));
this.TopPanel = new System.Windows.Forms.Panel();
this.Make = new System.Windows.Forms.Button();
this.LanguageType = new System.Windows.Forms.ComboBox();
this.NameSpace = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.CollectionClassName = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.ItemClassName = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.Code = new System.Windows.Forms.TextBox();
this.TopPanel.SuspendLayout();
this.SuspendLayout();
this.TopPanel.Controls.Add(this.Make);
this.TopPanel.Controls.Add(this.LanguageType);
this.TopPanel.Controls.Add(this.NameSpace);
this.TopPanel.Controls.Add(this.label3);
this.TopPanel.Controls.Add(this.CollectionClassName);
this.TopPanel.Controls.Add(this.label2);
this.TopPanel.Controls.Add(this.ItemClassName);
this.TopPanel.Controls.Add(this.label1);
this.TopPanel.Dock = System.Windows.Forms.DockStyle.Top;
this.TopPanel.Location = new System.Drawing.Point(0, 0);
this.TopPanel.Name = "TopPanel";
this.TopPanel.Size = new System.Drawing.Size(680, 40);
this.TopPanel.TabIndex = 0;
this.Make.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.Make.Location = new System.Drawing.Point(633, 12);
this.Make.Name = "Make";
this.Make.Size = new System.Drawing.Size(40, 24);
this.Make.TabIndex = 7;
this.Make.Text = "生成";
this.Make.Click += new System.EventHandler(this.Make_Click);
this.LanguageType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.LanguageType.Items.AddRange(new object[] {
"CSharp",
"VB.NET",
"JSharp"});
this.LanguageType.Location = new System.Drawing.Point(562, 14);
this.LanguageType.Name = "LanguageType";
this.LanguageType.Size = new System.Drawing.Size(70, 20);
this.LanguageType.TabIndex = 6;
this.NameSpace.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.NameSpace.Location = new System.Drawing.Point(447, 14);
this.NameSpace.Name = "NameSpace";
this.NameSpace.Size = new System.Drawing.Size(112, 21);
this.NameSpace.TabIndex = 5;
this.NameSpace.Text = "";
this.NameSpace.TextChanged += new System.EventHandler(this.NameSpace_TextChanged);
this.label3.Location = new System.Drawing.Point(372, 16);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(72, 16);
this.label3.TabIndex = 4;
this.label3.Text = "命名空间:";
this.CollectionClassName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.CollectionClassName.Location = new System.Drawing.Point(257, 14);
this.CollectionClassName.Name = "CollectionClassName";
this.CollectionClassName.Size = new System.Drawing.Size(112, 21);
this.CollectionClassName.TabIndex = 3;
this.CollectionClassName.Text = "";
this.label2.Location = new System.Drawing.Point(182, 16);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(72, 16);
this.label2.TabIndex = 2;
this.label2.Text = "集合类名:";
this.ItemClassName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.ItemClassName.Location = new System.Drawing.Point(67, 14);
this.ItemClassName.Name = "ItemClassName";
this.ItemClassName.Size = new System.Drawing.Size(112, 21);
this.ItemClassName.TabIndex = 1;
this.ItemClassName.Text = "";
this.ItemClassName.TextChanged += new System.EventHandler(this.ItemClassName_TextChanged);
this.label1.Location = new System.Drawing.Point(8, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(56, 16);
this.label1.TabIndex = 0;
this.label1.Text = "子类名:";
this.Code.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Code.Dock = System.Windows.Forms.DockStyle.Fill;
this.Code.Location = new System.Drawing.Point(0, 40);
this.Code.MaxLength = 0;
this.Code.Multiline = true;
this.Code.Name = "Code";
this.Code.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.Code.Size = new System.Drawing.Size(680, 349);
this.Code.TabIndex = 1;
this.Code.Text = "";
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(680, 389);
this.Controls.Add(this.Code);
this.Controls.Add(this.TopPanel);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "MainForm";
this.Text = "集合类生成器";
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
this.Load += new System.EventHandler(this.MainForm_Load);
this.TopPanel.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private void NameSpace_TextChanged(object sender, System.EventArgs e)
{
}
private void MainForm_Load(object sender, System.EventArgs e)
{
this.LanguageType.SelectedIndex =0;
}
private void Make_Click(object sender, System.EventArgs e)
{
this.ItemClassName.Text =this.ItemClassName.Text.Trim();
this.CollectionClassName.Text =this.CollectionClassName.Text.Trim();
this.NameSpace.Text =this.NameSpace.Text.Trim();
if(this.ItemClassName.Text.Length ==0)
{
MessageBox.Show("请输入要在集合类中包含的子类的名称。") ;
return;
}
if(this.CollectionClassName.Text.Length ==0)
{
MessageBox.Show("请输入集合类的名称。") ;
return;
}
if(this.NameSpace.Text.Length ==0 )
{
MessageBox.Show("请输入集合类的命名空间的名称。") ;
return ;
}
StrongTypeCollection.CodeType ct=new StrongTypeCollection.CodeType() ;
ct=(StrongTypeCollection.CodeType)this.LanguageType.SelectedIndex;
this.Cursor =System.Windows.Forms.Cursors.WaitCursor ;
this.Code.Text =StrongTypeCollection.Make(this.ItemClassName.Text, this.NameSpace.Text, this.CollectionClassName.Text, ct) ;
this.Cursor =System.Windows.Forms.Cursors.Default ;
}
[STAThread]
static void Main(string[] args)
{
Application.Run(new MainForm()) ;
}
private void ItemClassName_TextChanged(object sender, System.EventArgs e)
{
this.CollectionClassName.Text =this.ItemClassName.Text + "Collection";
}
}
}