fastCSharp代码生成器重新实现讨论帖

showjim 2012-11-05 12:57:34
加精
fastCSharp准备迁移代码生成器部分,我简单介绍一下我以前的实现(参考类库下载)。
1、C#程序模板是可编译的C#程序,不是文本文件。所以编写模板的时候,确定性的程序可以得到IDE的支持,包括错误提示、重构等。
2、模板与数据是分离的,输入参数主要是.net元数据和自定义属性组成视图,类似于网站概念里面的界面与程序分离。
3、在编译事件中执行,无需界面操作。

如果模板需要可编译,那么要符合C#语法规定。
1、使用@作为普通变量识别标志,后面接连续的英文、数字、下划线、小数点。比如:
return @type.fullName/**/.showjimCode.memberMap.memberNames;
type.fullName就是绑定视图数据的,/**/用做结束分隔符,因为后面接的是小数点。
2、有两种等价的逻辑格式定义,NAME用于绑定视图数据,开始符与结束符必须对称:
#region COMMAND [NAME]
//...
#endregion COMMAND [NAME]

/*COMMAND:[NAME]*/
//...
/*COMMAND:[NAME]*/

现在支持7种COMMAND
* LOOP/FOR 表示循环,NAME必须绑定到集合
* IF 绑定的数据为true或者不为null时输出代码
* NOT 绑定的数据为false或者为null时输出代码
* NOTE 表示屏蔽代码段输出,不需要定义NAME
* NAME 用于标识一个子段模板,可以被别的模板引用
* PART 用于标识一个子段程序代码,用于代码的分类输出
* VALUE 输出绑定的数据(这个很少用,一般情况用@替代)
不明白的结合看看setup\cSharp\template\*.cs

大家看看有什么问题,一起讨论,下个星期开始迁移代码生成器这部分程序(不包括模板)。
...全文
5274 72 打赏 收藏 转发到动态 举报
写回复
用AI写文章
72 条回复
切换为时间正序
请发表友善的回复…
发表回复
baodamang 2014-01-09
  • 打赏
  • 举报
回复
谢谢分享
showjim 2012-11-21
  • 打赏
  • 举报
回复
引用 68 楼 jAmEs_ 的回复:
万一逻辑要变,就全部手工改?
逻辑要变?能不能具体点。
xiaoxiaolumeng89 2012-11-17
  • 打赏
  • 举报
回复
谢谢你的分享
jAmEs_ 2012-11-17
  • 打赏
  • 举报
回复
引用 38 楼 sbwwkmyd 的回复:
引用 35 楼 sclc_2008 的回复:还不是很明白做这个目的 代码生成器,是根据程序模板生成逻辑类似的程序,替代那种“简单重复”的手写代码。 当然有些功能可以用反射来做,不过反射的运行效率比价差,在这种情况下代码生成就是又来取代反射的。 也有一些功能可以用AOP来做:有的实现有副作用(比如必须继承自某一个类,而且还是反射实现的);也有用Emit不用反射的实现,……
万一逻辑要变,就全部手工改?
LAONINGA098 2012-11-15
  • 打赏
  • 举报
回复
谢谢你的分享
qingyueq 2012-11-13
  • 打赏
  • 举报
回复
不懂,貌似很nb ..啊
showjim 2012-11-10
  • 打赏
  • 举报
回复
引用 59 楼 sp1234 的回复:
“迁移”? 不是随便用时髦术语的,对菜鸟应该使用(起码)正确一点的规范用语。
谢谢关注,重新设计+重写代码。 因为我也是菜鸟级别的,不懂规矩^-^。
  • 打赏
  • 举报
回复
“迁移”? 不是随便用时髦术语的,对菜鸟应该使用(起码)正确一点的规范用语。
  • 打赏
  • 举报
回复
支持,谢谢了
a1015795893 2012-11-09
  • 打赏
  • 举报
回复
哈哈哈 .....
showjim 2012-11-08
  • 打赏
  • 举报
回复
引用 49 楼 sclc_2008 的回复:
这个是生成程序,而不仅仅是静态的代码文件,可以这样理解吗?
是的,现在准备迁移的是用来生成程序的模板解析器。
songjinxi123 2012-11-08
  • 打赏
  • 举报
回复
学习了,顶一下。
sclc_2008 2012-11-08
  • 打赏
  • 举报
回复
引用 38 楼 sbwwkmyd 的回复:
引用 35 楼 sclc_2008 的回复:还不是很明白做这个目的 代码生成器,是根据程序模板生成逻辑类似的程序,替代那种“简单重复”的手写代码。 当然有些功能可以用反射来做,不过反射的运行效率比价差,在这种情况下代码生成就是又来取代反射的。 也有一些功能可以用AOP来做:有的实现有副作用(比如必须继承自某一个类,而且还是反射实现的);也有用Emit不用反射的实现,……
这个是生成程序,而不仅仅是静态的代码文件,可以这样理解吗?
tao2yue 2012-11-08
  • 打赏
  • 举报
回复
谢谢,
钱币老顽童 2012-11-08
  • 打赏
  • 举报
回复
lyn_200593020 2012-11-07
  • 打赏
  • 举报
回复
顶一个 好啊 真好啊
ChenKe0502 2012-11-07
  • 打赏
  • 举报
回复
顶。。。。。。。
  • 打赏
  • 举报
回复
标记一下,以后好好看
裸奔的蜗牛 2012-11-07
  • 打赏
  • 举报
回复
谢谢,这个文章很好
厐厐 2012-11-07
  • 打赏
  • 举报
回复
楼主牛逼~~
加载更多回复(31)
在算法相同的情况下,运行效率最好的程序是怎么产生的?我知道那一定是硬编码的。但是硬编码开发时间最长,维护成本最高,最容易出错。所以没有多少人会一直坚守这个阵营。 我们需要降低开发成本,提高程序的可维护性。所以编程语言一直在朝着开发效率方面不断的进化,抽象能力越来越强。一般来说,编程语言的抽象能力越强,意味着代码量越少,程序的可维护性越高。与此同时,程序的运行效率也是越来越低。 到底是选择运行效率,还是选择开发效率?对很多人来说,这是个纠结的问题。人们的选择总是多样化的,有的人抛弃了运行效率,有的人抛弃了开发效率,有的人选择多种语言相互调和。 当然我也要做出自己的选择,那么它就是C#,因为不论是运行效率还是开发效率,它都能做到很不错。 我采取的方案是自动化+硬编码,自动化的实现方式是静态代码生成,硬编码主要针对于静态代码生成的模板程序。 我创建这个项目,目的是为了集思广益,更好的使用C#,打造一个“开发+运行”效率双优的开源框架,所以项目命名为fastCSharp。 由于我个人基本上只有web开发经验,所以我贡献的代码部分包括web开发部分,没有桌面应用部分,其它的就靠大家贡献了。 代码贡献者请注意:为了解决部分桌面应用平台升级问题,这个项目决定兼容.net framework2.0。 我个人贡献的内容主要包括五个方面: 1、数据集合操作支持.net2.0的链式编程体验(此部分现已迁移完毕)。 * 链式编程的核心思想是想到什么就点什么,程序书写思路更流畅。但要注意的是不要把程序写成一行,对于带参数的函数调用,最好是一行一个点,否则异常了都不知道哪里出的问题,比如: return diantou.dataProxy.questionTopic.getLinkIds(id) .getArray(value => diantou.dataProxy.question.get(value)) .getHash(value => value.bestAnswerId) .getArray(value => diantou.dataProxy.answer.get(value)) .getFind(value => value != null) .group(value => value.userId) .getArray(value => new KeyValuePair(diantou.dataProxy.user.get(value.Key), value.Value.Count)) .group(value => value.Key.grade0) .getArray(value => new userStat { grade0 = value.Key, count = value.Value.Count, path = topic.path.bestAnswer, users = value.Value.rangeSort((left, right) => right.Value - left.Value, 0, 6) .getArray(user => diantou.dataProxy.user.get(user.Key, userId)) }); 2、基于.net元数据的静态代码生成器(下面会有相关介绍)。 3、我常用的几种C#程序模板,包括快速序列化、TCP网络通讯、SQL操作实体类、Web视图、单元测试等。 * 数据序列化一般用于网络通讯,非文本数据对象的序列化效率是.net的50倍以上。 * TCP网络通讯调用和调用本地函数一样简单。比如我配置好网络服务参数: public enum enumType { [showjim.config.tcpCall.server(Register = showjim.config.setup.register.DataProxy, IsRegisterOnly = true, VerifyFileName = showjim.config.setup.pub.VerifyFileName, ClientCount = 500, IsAsynchronous = false, IsCompress = false)] DataProxy, } 然后定义了一个网络函数: [showjim.setup.attribute.tcpCall(server = showjim.config.tcpCall.server.enumType.DataProxy)] public partial class favorite : diantou.dataModel.favorite.showjimCode.proxy, showjim.sys.setup.Copy { [showjim.setup.attribute.tcpCall] private static favorite[] GetUser(int id, int pageSize, int currentPage, int userId, out int count) { favorite[] values = GetUsers(id, userId); array.page page = new array.page(count = values.length(), pageSize, currentPage); return values.sub(page.SkipCount, page.CurrentPageSize).toArray() .getArray(value => value.setUser(userId)); } } 网络调用就像下面这么简单(多一个.client): protected diantou.dataProxy.favorite[] MyFavorite { get { return diantou.dataProxy.favorite.tcpCall.client.GetUser(CurrentUser.id, PageSize, query.page, CurrentUserId, out ItemCount); } } * SQL实体类只提供单表操作,但是提供细节操作,比如只更新某一字段。多表操作建议使用缓存模式(毕竟内存比人工优化便宜),采用链式编程处理。不过缓存模式不适应于数据量比较大的单机应用,我想单机应用一般也不会有多大数据量吧。 * Web视图数据实现按需取值(html模板用到什么取什么),紧凑拼接,无带宽浪费,不使用反射。比如我现在访问的http://www.51nod.com/today.html#!type=all,未压缩的页面数据只有1.55K,普通的ajax数据格式就算压缩了也比这个大。 * 另外还有URL查询字符串的自动解析功能,不用自己去转换查询参数Fomr["XXX"],参数或者字段定义什么类型就会自己接受什么类型。 4、与Web视图配套的js类库,包括数据驱动界面的实现、ajax功能、html编辑器、简单的筛选器、以及一些常用功能。 * 数据驱动界面,这个需要体验一下,比如在未登录的状态下访问http://www.51nod.com/today.html#!type=all,在浏览器地址栏输入 [removed]alert(Showjim.PageView.SkinValue.header.Set({focus:{count:1,isCurrent:1}})); 或者在调试器里执行 Showjim.PageView.SkinValue.header.Set({focus:{count:1,isCurrent:1}}); 可以看到界面的变化。 5、一个简易的web服务器,实现部分了http1.1。 * www.51nod.com就是用这个做的web服务器,功能还有待完善。 前3个可应用于桌面,后两个应用于web,其实web服务器有时候也能应用于桌面或某些代理应用。 这里介绍一下代码生成器。 很多人认为代码生成==ORM。这里必须要纠正一下这个观念,ORM只是代码生成的一种应用场景。代码生成是一种自动化的实现,同时也是一种抽象方式,就好像面向对象也是一种抽象方式。 静态代码生成的实现方式也是多样的,最简单的模板是写程序直接拼接字符串,还有用VS自带的T4模板,一般来说都是面向文本文件的生成。 我使用的代码生成器有三个特点: 1、它的C#程序模板也是可编译的C#程序,不是文本文件。所以编写模板的时候,确定性的程序可以得到IDE的支持,包括错误提示、重构等。 2、它的模板与数据是分离的,它的输入参数主要是.net元数据和自定义属性组成视图,类似于网站概念里面的界面与程序分离。 3、它可以在编译事件中执行,无需界面操作。 在我的项目里,代码生成可以说是无处不在,有的时候是为了取代反射改善运行效率,有的时候是为了更方便的编写程序,有的时候是为了自动单元测试...那你将是为了什么呢? 我贡献的内容属于基础框架,不关联业务逻辑,所以没有几分钟开发一个XXX系统的能力。那个属于业务建模的范围,但是我希望这个框架能够助你快速实现模型。 使用这个框架搭建一般的网站,主要的工作量在于编写业务逻辑和提供数据视图。

13,347

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET技术前瞻
社区管理员
  • .NET技术前瞻社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧