在编写 C# 程序时,通常会有很多模式类似的代码,需要反复编写,这时候代码生成器就成了一个很有用的东西,可以大量降低人的重复劳动。
原先我也看过 CodeSmith 等生成工具,但是要去学习它们的模板语言通常也需要时间成本,或者需要费一些气力才能达到自己想要的效果。
另外,CodeDOM,Emit 等 C# 技术虽然有所研究,总感觉用来作这种事情实在是既累也不讨好,除了锻炼技术之外没别的好处。
费话不多说,今天我写了两个简单的 python 程序来做这个事情,其中利用了 python 的带名称的格式化参数的特性,使得代码非常简单。
集合类生成工具:
#
encoding=gb2312
def
make_collection_class(entity_name, entity_comment):
template
=
"""
using System.Collections;
namespace SomeNameSpace.Model
{
/// <summary>
/// %(entity_comment)s集合
/// </summary>
public class %(entity_name)sCollection : CollectionBase
{
public %(entity_name)sCollection()
{
}
public void Add(%(entity_name)s obj)
{
base.InnerList.Add(obj);
}
public void Remove(%(entity_name)s obj)
{
base.InnerList.Remove(obj);
}
public %(entity_name)s this[int i]
{
get { return (%(entity_name)s) base.InnerList[i]; }
set { base.InnerList[i] = value; }
}
}
}
"""
return
template
%
locals()
print
make_collection_class(
'
MyDocument
'
,
'
我的文档
'
)
生成结果如下:
using
System.Collections;
namespace
SomeNameSpace.Model
{
///
<summary>
///
我的文档集合
///
</summary>
public
class
MyDocumentCollection : CollectionBase
{
public
MyDocumentCollection()
{
}
public
void
Add(MyDocument obj)
{
base
.InnerList.Add(obj);
}
public
void
Remove(MyDocument obj)
{
base
.InnerList.Remove(obj);
}
public
MyDocument
this
[
int
i]
{
get
{
return
(MyDocument)
base
.InnerList[i]; }
set
{
base
.InnerList[i]
=
value; }
}
}
}
再来一个实体类的生成代码:
#
encoding=gb2312
def
make_entity_class(class_name, class_name_comment, properties):
property_template
=
"""
%(type)s _%(property)s;
public %(type)s %(property)s { get { return _%(property)s; } set { _%(property)s = value; }}
"""
pstr
=
""
;
for
p
in
properties:
pstr
+=
property_template
%
({
"
type
"
: p[
1
],
"
property
"
: p[0]
})
class_template
=
"""
namespace SomeNameSpace.Model
{
/// <summary>
/// %(class_name_comment)s
/// </summary>
public class %(class_name)s
{
%(pstr)s
}
}
"""
return
class_template
%
locals()
print
make_entity_class(
'
Office
'
,
'
办公室
'
, [
[
'
OfficeId
'
,
'
int
'
],
[
'
OfficeName
'
,
'
string
'
]
])
生成的实体类如下:
namespace
SomeNameSpace.Model
{
///
<summary>
///
办公室
///
</summary>
public
class
Office
{
int
_OfficeId;
public
int
OfficeId {
get
{
return
_OfficeId; }
set
{ _OfficeId
=
value; }}
string
_OfficeName;
public
string
OfficeName {
get
{
return
_OfficeName; }
set
{ _OfficeName
=
value; }}
}
}
目前这两个代码的功能可以说非常简单,因为之前一直有想法用 python 做代码生成器,今天当做是一个起步吧:)
下面的目标是要实现有 UI 的,能够读取分析模型文件,或者数据库 Schema 的工具。