Hello World
Spiga

谈吉日嘎拉的《白话反射技术》及其他(技术篇)

2009-10-16 19:16 by 老赵, 20837 visits

社区又掀起了腥风血雨,这次又是吉日嘎拉这一博客园的众矢之的所引发的惨案。他的一篇《白话反射技术》发表之后,被包同学一篇文章狠狠地踩在脚底下,言辞之激烈令人罕见。从两片文章的内容与评论来看,大家的眼光似乎都没有集中在技术本身,而是针对个人在你来我往。有评论称这是“门派之争”,虽然看不出到底哪门哪派,但看上去也还真像那么一回事情。不过这真是技术社区该有的讨论氛围和方式?如果觉得吉日嘎拉在技术上有问题,难道不应该条条指出吗?既然没有人做这件事情,那么就还是我来吧,反正我写博客也成习惯了。

文章还是分两篇吧。先谈技术,再谈非技术——这样某些朋友也可以有选择地忽略某个部分。

反驳一个人的观点,我认为最简单而直接的方式是逐条批驳,必要的时候可以引用原文。首先,吉日写到:

使用反射有几个误区:反射的性能慢?其实未必反射的性能是慢的,说不定有些场合,反射的性能是更快更高效的,不用它的优点,用了他的弱点,那就无法达到高效的目的了,文章的结尾也说说我的观点。

我同意他的部分观点。“反射性能差”的确是相对的,例如反射调用一个方法,访问一个属性的确比直接访问要慢上许多。但是对于一个普通应用程序来说,反射几乎不会成为性能瓶颈,因为性能瓶颈往往是由外部IO操作造成的。例如,一个数据库访问,一个Web Service调用,就算是有朋友认为的Remoting这个性能非常高的分布式调用方式,它的通信性能也远比反射要慢好几个数量级。假设一个反射消耗的时间是0.0001秒,那么它的确比直接调用消耗的0.0000001秒慢上一千倍,但是它还是可以在1秒钟执行1万次,不是吗?但是我们平时的SQL查询,有哪个可以如此高效?

此外,我们现在也有很多方法可以加快反射调用的性能,例如我曾经写过的一个简单小类库,可以保持反射调用的方法不变(如只是把Invoke方法调用变成了FastInvoke),但是性能也接近了直接调用。这是因为使用了Emit动态生成了IL代码,这样在调用的时候便和直接调用如出一辙。对于需要大量使用反射的场景,例如NHibernate需要通过反射为属性一个一个赋值,那么它一般也会使用类似的机制来提高性能。

至于是否有“某些场合”反射的性能是更快更高效的,我想不出来。不过如果只是“利用了它的弱点”,那一定是不合适的,这就是所谓的“滥用”。

我在日常开发中反射常用的几个环节,其实架构师架构系统反射等用得多,程序员日常开发里,其实不懂也没啥大不了的。

我“直觉上”不同意这种使用“架构师”、“架构系统”来划分反射作用适用性的方式,但事实上我也无法在这方面说出个所以然来。或者说,我只能说一句废话:“该用反射的时候就使用反射”,普通程序员还是一定要懂反射的。

在很多时候反射也是唯一的选择。为什么我们会选择使用反射?因为我们没有办法在编译期通过静态绑定的方式来确定我们要调用的对象。例如一个ORM框架,它要面对的是通用的模型,此时无论是方法也好属性也罢都是随应用场景而改变的,这种完全需要动态绑定的场景下自然需要运用反射。还例如插件系统,在完全不知道外部插件究竟是什么东西的情况下,是一定无法在编译期确定的,因此会使用反射进行加载。其实,包同学的反驳文章里也是持这种观点的:

最后,不要怀疑反射的应用,三层架构中的数据层和DB的Mapping,AddIn架构,都离不开反射。这个话题说起来就大了,没有几年的项目实际是感受不到的。

“数据层和DB的Mapping”或是“AddIn架构”,其实都是架构层面的内容,刚好符合日吉的观点“其实架构师架构系统反射等用得多”,那么这架究竟是怎么吵起来的呢?

接下来吉日展示了他使用反射的常见场景。其中提到:

两个类,需要互相调用了,不能直接进行互相引用了,那不是死循环了?例如我这里2个包里的窗体之间,需要互相调用,就用了反射技术,直接动态的从dll 包里把相应的窗体呼叫出来,当然我也不想用反射但是不用不行了,没有其他更好的解决方法了,我不是为了玩技术用技术,而是实际开发中遇到问题了不用不行了,才用反射技术。

……

我们在开发大型软件项目时经常会遇到,系统很庞大了有几百M的代码了,主程序启动时,总不能把这些都引用了吧?全部加载在内存里?那程序的启动速度,不知道会不会慢如老牛推车了?这时候也会用一些反射技术等,用到哪个窗体,就动态加载哪个那个窗体,总感觉比较清爽一些。

在我看来,这段话可谓完全是错误的

两个类,如果需要互相引用,那也就是产生了双向依赖。如果这是设计上的问题,那就应该从设计的角度来解决。如果“直接动态从dll包里把相应的窗体呼叫出来”,这难道还不是一种双向依赖吗?难道因为“编译期”可以通过了,在“运行时”就解耦了?这只是把依赖关系给隐藏起来了,“总感觉清爽一些”,这平白无故的感觉要不得。这种反射的使用方式在我看来就是一种滥用,因为这完全可以在编译期通过静态绑定的方式来确定调用目标。如果使用反射,那么就无法由编译期来进行检查,这样项目的第一道防线也就丢失了。

根据吉日的观点:“系统有几百M的代码,主程序启动时把所有的代码都加载了”。事实上,CLR并不会这么做。如Essential .NET所云

The CLR loader is responsible for loading and initializing assemblies, modules, resources, and types. The CLR loader loads and initializes as little as it can get away with. Unlike the Win32 loader, the CLR loader does not resolve and automatically load the subordinate modules (or assemblies). Rather, the subordinate pieces are loaded on demand only if they are actually needed (as with Visual C++ 6.0's delay-load feature). This not only speeds up program initialization time but also reduces the amount of resources consumed by a running program.

事实上,CLR只有在真正需要某个程序集的时候才会进行加载,因此不会因为程序庞大而“启动速度慢如老牛推车”。

而接下来,吉日写的是大家最常见不过的“通过反射加载数据访问层来应对不同数据库”:

我只写一份商业逻辑,但是希望能跑在多种数据库上,我配套每种数据库的商业逻辑部分都相应的写一份,那我的工作量是加倍的,每个包都要进行测试、维护、升级、改进、调试、优化,世界超级大国美国也只能同时进行2个局部战争,你能同时谈3-4个女朋友,那我真服了有本事啊,一般会没多久就会穿帮了,维护几个数据库访问方法倒是不会工作量很大,相对来讲是有限的。

……

配置文件里,明确指出,我需要用什么数据库,什么连接串等。

……

我的数据库访问工厂里,按配置读取相应的数据库连接类、实例化相应的类。

……

这也是典型的使用方式,被无数人翻来覆去写过,被更多人翻来覆去使用过的方法。PetShop也是这种做法,因此虽然我不喜欢这个,但我也的确挑不出毛病来。

我说我不喜欢这种方式,是因为我认为这种数据访问层的写法过于机械,也比较难以使用,代码较多,经历了几个项目之后我被搞得非常疲惫。我目前比较欣赏的方式是基于ORM框架编写的数据访问层。我接下来也打算谈谈我理想中的设计,不过这里就不多谈了。

我发现,其实这也是包同学提出的反射场景之一……我真的搞不明白,这一架究竟是怎么吵起来的!?

这些用到的反射、系统架构时调试通过了,别人也根本没兴趣研究了,也不需要所有的人都折腾反射,偶尔需要用时,照葫芦画瓢就可以了,先copy然后past,然后修改几个名称什么的,然后run,运行正常了,就懒得管了,不行就dbug。

我们公司没几个人用到反射,公司里估计就2个人,其中一个也是用DNT的现成的,我这个是自己折腾出来的。实际工作中需要了,就用用,或者想学技术,就自己弄弄,没必要为了显示你技术都少厉害非牵扯个反射出来。

“没必要为了显示你技术多少厉害非牵扯个反射出来”,我同意。技术的确是为了用的,不是为了显摆的,但是这并不是“不去学反射”的理由。这也是我不喜欢吉日最主要的原因,就是他对于技术的一种“无所谓”的“将就”态度。一直听到这种说法,技术不用特地学,等用到了再学,边学边用。但是,如果你不去学技术,又如何可以得知哪个技术适合你目前的使用场景?有很多朋友说工作就是日复一日的重复,没有长进。这可能是多种原因造成的,但是我想如果抱着“不主动学习技术”的心态,那么不断重复还真不是“无法想象”的情况。

但也有朋友会回复说,有些人他的确不是热爱技术的人,也只喜欢过普通的日子,我和他们不是一个情况,无法理解。的确,我可能真的无法理解,因此我也只能不断地推广、表达、推广我对技术的理念,而不会,也无法把自己的观点强加给别人。

最后,吉日谈了他最讨厌的反射使用场景:

or mapping 什么的,一个类里的属性,方法通过循环读取出来,然后一个类的保存,读取,能自动实现什么的,若有10000个对象的,每个对象有50个属性,那得循环多少次?不是循环死人啊?还有就是 .net 的类型与数据库类型的转换匹配,null 的匹配等空日期的匹配转换,多种数据库类型的转换,我看了这样的代码,就恶心想吐,为了提高性能还需要延迟加载什么的搞得死去活来,我们不是搞研究玩技术的,把项目又快又好又简单的做好,客户满意,能及时拿到项目款就可以了,杀鸡用刀就可以了,别还先打一会儿太极,再品茶啥的,赶紧杀鸡啊,我看着都心急。

后来事实证明,代码生成器还是蛮好用的,不是靠反射循环搞定问题,而是通过机器来产生代码,这个的确比较好,我也喜欢。我也曾经用过很多乱八七糟的技术,现在懒得玩,懒得学习了,跟着微软屁股后面跑微软哪个成熟了,我就玩那个,平时关注一下发展动向,不是微软的能不用就不用了,我不想折腾了。

单个技术,都是非常好的,但是组织到一起就容易乱套了,不伦不类,而且把性能优化到最好需要更高的水平了。

ORM是大量使用了反射,它的代码的确也“不甚美观”,因为反射本身是很丑陋(好吧,应该说是“麻烦”)的调用方式(C# 4.0的dynamic关键字则很好的解决了这个问题)。但是这不正常吗?我曾经在互联网上看到过这个说法:“任何美丽的接口后面都有丑陋的实现”,美妙的接口,好用API,它的目的就是帮你在项目中避免“亲自”操作这些丑陋的内容。

ORM框架的作用就是为了帮助开发人员更好的完成项目,把大量复杂的实体和数据库的关系映射起来,并且实现了常用的CRUD和具有一定程序灵活性的查询方式。我现在是完全离不开ORM了,我理想中的数据访问层设计也是沿袭了ORM的使用方式。而NHibernate的首席开发人员Oren Eini还在他的一次NDC的演讲中认为不该为数据访问层花费任何时间,应该把时间放在和业务相关的代码上面,否则就是浪费金钱。

换句话说,使用ORM框架,其实就正好符合吉日“把项目做的又快又好又简单”的要求。的确,学习ORM需要成本,但也有俗话说“磨刀不误砍柴功”。如果说为了某个项目特地磨刀是浪费时间,加大风险,那么为什么不就在平时点滴时间内进行学习呢?如果你不学,那么你下个项目还是不会用,这样“要用再学”也永远只能是个梦想了。

至于代码生成器,的确好用,我也推荐多用。吉日在这里至少比手动硬写数据访问层的人聪明多了。他对于技术的态度,我还是不喜欢,但是可能的确可以反应一部分人的想法。

对于吉日文章的技术部分评价我就写到这里了,的确有不少问题,但也并非无一可取之处。看许多朋友和吉日的冲突,也大都是“意识形态”方面的问题吧。但既然是技术社区,那么我们至少也应该在技术角度上“率先”给予反馈——或反击吧?

嗯,我已经处理完技术方面的问题,那我也立即开始非技术方面的准备了(“吵架篇”在此)。

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

88 条回复

  1. helloj2ee
    *.*.*.*
    链接

    helloj2ee 2009-10-16 19:21:00

    说实话 刚刚看到 我都不想在包的帖子上发表评论 那篇文章对我而言 除了包的推荐反射以外 实在是没有其他的好处。个人有个人的活法 现在这个世界是笑贫不笑娼 现在耍流氓的太多了。大家不要光顾着看某某人火气大 要想想背后火气大的原因。难道真是怕耽误新人学习吗?说实话也太高估吉日的帖子的威力了吧。
    做技术更重要的是人品 好了。说到此为此.......

  2. enou_wang
    *.*.*.*
    链接

    enou_wang 2009-10-16 19:25:00

    一年前我甚至不知道博客园为何物。但三个月前我我看了老赵您讲的“Ajax系列课程”(虽然是你在两年前讲的,那时我还在上学,竟然不知道),从而知道您的博客,进而了解到原来中国也有这样对技术专研,痴迷的“狂人”,不都是Ctrl C+V,然后就“盯”上了您,最后喜欢上园子里的这种氛围。
    网络资源很丰富,但其实有时当你真正的去搜索一点技术上的东西,你会发现你什么都搜不到,或是搜到20篇,没等兴奋你会发现有十九篇内容是一样的,也许高手们都是传统的“厚积薄发”型,应该“有积就发”嘛,不要防备自己国家的同行,和中国所有的程序员分享,国家的软件产业才会得到更好发展,都想您这样,中国何愁软件行业的前途(题外话,扯远了)。
    话说回来,我刚刚注册了博客园,这是我第一次给您留言,老赵您以后的担子更重了,因为多了一个像我这样“崇拜”你的人,你的一个不小心有可能给我们带来的是思维上的误导,当然您的坚持,也会给我们带来莫大的动力。加油!

  3. ouzi2[未注册用户]
    *.*.*.*
    链接

    ouzi2[未注册用户] 2009-10-16 19:37:00

    不管怎么说,包包的话真的充满了的火药味。。。也许,他正在想,我为社区摇旗呐喊,清理了一个***的人,站在了“正义”的一边,我多帅,可是,口乃心之门户,可见包包,在有些方面有待提高,

  4. 老赵
    admin
    链接

    老赵 2009-10-16 19:38:00

    @ouzi2
    我反感对人不对事,我反感技术讨论时扯上“人品”等乱七八糟的东西。

  5. Ariex[未注册用户]
    *.*.*.*
    链接

    Ariex[未注册用户] 2009-10-16 19:42:00

    有些像了解“web标准化”的人对鼓吹“DIV+CSS说法”的人的发自内心的厌恶吧……
    错误的说法确实对新手会产生非常差的影响

  6. ouzi2[未注册用户]
    *.*.*.*
    链接

    ouzi2[未注册用户] 2009-10-16 19:48:00

    如果老赵你认为,我在你的地盘上讨论了关于“人品”问题,你可以删除我的评论,没有关系的

  7. 亚历山大同志
    *.*.*.*
    链接

    亚历山大同志 2009-10-16 19:52:00

    说句主观的话我反感吉日,客观的来说其实很多人不喜欢吉日的原因还真是老赵总结的,对待技术无所谓的态度

  8. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-16 19:53:00

    完全支持,顶,这才是反驳别人的正确方式,逐条驳斥。

    PS:我觉得你有一条理解错了吉日原文的意思(我猜想你很少做WinForm的应用)。
    比如,大一点的WinForm应用肯定会划分很多子模块。实际上只有使用到这个模块的功能(比如点击某个菜单)的时候才需要加载它。如果不用反射我们如何做到这点?
    一般做法肯定是,通过一个xml文件或者什么生成主界面的主菜单,当点击该菜单的时候,根据xml文件里设置的类型,加载相应的模块。
    (.Net本质论说的肯定是正确的,只是如果不用反射,这些模块就必须在编译时就引用、使用到)

    这几天一直在寻找关于WinForm架构的Best Practice。

  9. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-10-16 19:59:00

    横刀天笑:
    完全支持,顶,这才是反驳别人的正确方式,逐条驳斥。

    PS:我觉得你有一条理解错了吉日原文的意思(我猜想你很少做WinForm的应用)。
    比如,大一点的WinForm应用肯定会划分很多子模块。实际上只有使用到这个模块的功能(比如点击某个菜单)的时候才需要加载它。如果不用反射我们如何做到这点?
    一般做法肯定是,通过一个xml文件或者什么生成主界面的主菜单,当点击该菜单的时候,根据xml文件里设置的类型,加载相应的模块。
    (.Net本质论说的肯定是正确的,只是如果不用反射,这些模块就必须在编译时就引用、使用到)

    这几天一直在寻找关于WinForm架构的Best Practice。




    是不是理解为使用反射延迟编译而不是延迟加载。

    因为事实上CLR确实是用到时加载。

  10. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-16 20:03:00

    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?

  11. 老赵
    admin
    链接

    老赵 2009-10-16 20:05:00

    ouzi2:如果老赵你认为,我在你的地盘上讨论了关于“人品”问题,你可以删除我的评论,没有关系的


    没事,我也没法做到不讨论这些东西……

  12. kyorry
    *.*.*.*
    链接

    kyorry 2009-10-16 20:08:00

    虽然我看不惯吉日写文章的语气和态度,不过和吉日相比,我更看不惯包的态度,比吉日差多了……

    拿着吉日做文章上头条,发一堆愤青的话,连吉日都不如!

  13. 亚历山大同志
    *.*.*.*
    链接

    亚历山大同志 2009-10-16 20:08:00

    横刀说的动态加载dll是指在winform中动态加载plugin的方式

  14. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-10-16 20:10:00

    话说我们是不是应该不要在这个技术篇讨论态度或者其他问题?老赵不是承诺去写非技术篇了么?

  15. Ryan Gene
    *.*.*.*
    链接

    Ryan Gene 2009-10-16 20:12:00

    有一点我不太明白,其实大多数人都知道吉日的文章质量并不是很高,有些还有广告之嫌,为什么管理员一直放任呢?为了人气?或者因为吉日文章篇幅比较长?我觉得管理团队是在打造这样一个人。但我觉得这样得不偿失。

  16. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-16 20:14:00

    @亚历山大同志
    嗯,其实我觉得做这种类型的WinForm应用必须使用Plugin的方式加载子模块(当然,不管你的plugin架构是完善,还是简陋,或仅仅就是一个反射)。

  17. kyorry
    *.*.*.*
    链接

    kyorry 2009-10-16 20:21:00

    helloj2ee:
    说实话 刚刚看到 我都不想在包的帖子上发表评论....大家不要光顾着看某某人火气大 要想想背后火气大的原因。难道真是怕耽误新人学习吗?说实话也太高估吉日的帖子的威力了吧。
    做技术更重要的是人品 好了。说到此为此.......


    完全同意!

  18. 寒星
    *.*.*.*
    链接

    寒星 2009-10-16 20:22:00

    貌似我去晚了,好象没有包同学的回复了?唉,感觉最近看到有包同学在的帖子必须有些许火药味,我的错觉?

  19. Ryan Gene
    *.*.*.*
    链接

    Ryan Gene 2009-10-16 20:25:00

    吉日有句口头禅,谁写的文章比他牛他就佩服谁,我觉得这篇吉日应该来佩服下

  20. Joyaspx
    *.*.*.*
    链接

    Joyaspx 2009-10-16 20:33:00

    我的个神啊,别人是几天一片文章,你是一天几篇文章,真怀疑是不是请人代笔了

  21. 春晚[未注册用户]
    *.*.*.*
    链接

    春晚[未注册用户] 2009-10-16 20:38:00

    期待老赵,包包,还有吉日3P.

  22. dark
    *.*.*.*
    链接

    dark 2009-10-16 20:41:00

    WinForm里面的Form比如这样的
    [code]
    delegate void A(string name);
    A a = new A(/*void 伪代码*/);
    Form1 f = new Form1();
    f.Invoke(a,"名字");//这里的Invoke用到反射没啊 老赵....
    [/code]

  23. 寒星
    *.*.*.*
    链接

    寒星 2009-10-16 20:54:00

    春晚:期待老赵,包包,还有吉日3P.


    Ryan Gene:有一点我不太明白,其实大多数人都知道吉日的文章质量并不是很高,有些还有广告之嫌,为什么管理员一直放任呢?为了人气?或者因为吉日文章篇幅比较长?我觉得管理团队是在打造这样一个人。但我觉得这样得不偿失。


    个人认为没多少人会去看他的文章,久而久之没市场也就罢了,他也有言论的自由嘛。不过,如果一直放水文到首页,管理团队还是要辛苦一下才对。

  24. 黄明
    *.*.*.*
    链接

    黄明 2009-10-16 21:02:00

    老赵说的很中肯,包包那厢有点愤。

  25. 老手[未注册用户]
    *.*.*.*
    链接

    老手[未注册用户] 2009-10-16 21:05:00

    看来有人的地方就有江湖,这话一点没说错。
    吉日的文章广告越来越多了,吹牛吹破天了,看来是博主没有限制任其发展的结果,这大恶人快练成九阴真经了,看来博客园得变变规矩了。

  26. 寻自己
    *.*.*.*
    链接

    寻自己 2009-10-16 21:06:00

    Ryan Gene:有一点我不太明白,其实大多数人都知道吉日的文章质量并不是很高,有些还有广告之嫌,为什么管理员一直放任呢?为了人气?或者因为吉日文章篇幅比较长?我觉得管理团队是在打造这样一个人。但我觉得这样得不偿失。


  27. 亚历山大同志
    *.*.*.*
    链接

    亚历山大同志 2009-10-16 21:15:00

    @dark
    winform控件的invoke和反射调用的那个invoke是两码事

  28. 王德水
    *.*.*.*
    链接

    王德水 2009-10-16 21:16:00

    分析文章的对与错,非常好。这样我们就可以让社区里的人慢慢的相互提高。

    我们把社区也当作敏捷的话,不用特意的去苛求。

    最终不适合的人会被 “挤出”去的,或者自己就觉得没意思。

    大浪淘沙。

    拿毛主席的话说 :天若有情天亦老,人间正道是沧桑。

  29. 老手[未注册用户]
    *.*.*.*
    链接

    老手[未注册用户] 2009-10-16 21:17:00

    包同学义愤填膺可以理解,只不过是怒不择言了,奉劝一句,江湖中鱼龙混杂,免得气大伤身,得不偿失。
    我以为博客园还是以讨论技术为主,广告帖和水帖还应当有所限制。

  30. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-16 21:46:00

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?



    CLR确实解决不了这个问题。只能自己来动态加载。

  31. lovecherry
    *.*.*.*
    链接

    lovecherry 2009-10-16 21:48:00

    技术社区有理有据讨论技术,对事不对人,其实说人品真没意思,谁能说自己一点私心都没有百分百无私奉献,其实这都不重要,重要的是分享了东西别人学到了,很多人就留言说什么垃圾,至少人家还有点垃圾出来,有些人只会骂什么都不留下。惭愧惭愧,强烈同意老赵说法修改首页排名,把我踢出100吧,很久不更新了

  32. Clingingboy
    *.*.*.*
    链接

    Clingingboy 2009-10-16 21:51:00

    为自己喜爱的技术维权,呵呵.

    无反射,无架构...
    反射让生活更美好...
    我讨厌代码生成...

  33. 包建强
    *.*.*.*
    链接

    包建强 2009-10-16 22:05:00

    lovecherry:技术社区有理有据讨论技术,对事不对人,其实说人品真没意思,谁能说自己一点私心都没有百分百无私奉献,其实这都不重要,重要的是分享了东西别人学到了,很多人就留言说什么垃圾,至少人家还有点垃圾出来,有些人只会骂什么都不留下。惭愧惭愧,强烈同意老赵说法修改首页排名,把我踢出100吧,很久不更新了



    你那里起码还有《无废话C#设计模式》,下次他要是唧唧歪歪设计模式,就把这套好东西拿出来show给他看。不然还真以为博客园是鱼目混杂之地了。

  34. Nick Wang (懒人王)
    *.*.*.*
    链接

    Nick Wang (懒人王) 2009-10-16 22:24:00

    道法自然:

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?



    CLR确实解决不了这个问题。只能自己来动态加载。



    我记得是jit,只有用到改模块的代码是才会加载。

  35. Nick Wang (懒人王)
    *.*.*.*
    链接

    Nick Wang (懒人王) 2009-10-16 22:28:00

    如果只是为了启动快而使用反射的化……那你真的比较过两种方法的启动时间么?还是只是想当然呢?

    任何没有实际测试和度量的优化,都不是优化。

  36. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-16 22:31:00

    @Nick Wang (懒人王)

    你说的对,就是JIT要用到的时候,才会去加载,把这给忘了,我说错了。我就是基础不扎实带来的缺点,否则就会滥用动态加载了。

  37. 老赵
    admin
    链接

    老赵 2009-10-16 23:11:00

    道法自然:

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?


    CLR确实解决不了这个问题。只能自己来动态加载。


    我觉得可以根据良好的设计来避免直接加载啊,我还不确定,我试试看吧。

  38. 老赵
    admin
    链接

    老赵 2009-10-16 23:14:00

    lovecherry:技术社区有理有据讨论技术,对事不对人,其实说人品真没意思,谁能说自己一点私心都没有百分百无私奉献,其实这都不重要,重要的是分享了东西别人学到了,很多人就留言说什么垃圾,至少人家还有点垃圾出来,有些人只会骂什么都不留下。惭愧惭愧,强烈同意老赵说法修改首页排名,把我踢出100吧,很久不更新了


    我从来没有说过希望修改首页排名……

  39. 老赵
    admin
    链接

    老赵 2009-10-16 23:26:00

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?


    我思考过了,应该是用户不点菜单是不会加载的才对,你是怎么做的导致核心模块和其他模块一定要一起加载呢?

  40. kisskiki[未注册用户]
    *.*.*.*
    链接

    kisskiki[未注册用户] 2009-10-16 23:33:00

    Jeffrey Zhao:

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?


    我思考过了,应该是用户不点菜单是不会加载的才对,你是怎么做的导致核心模块和其他模块一定要一起加载呢?


    难道是不同的dll,当点击菜单才jit编译加载?不知道我理解的对不对

  41. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-16 23:40:00

    Jeffrey Zhao:

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?


    我思考过了,应该是用户不点菜单是不会加载的才对,你是怎么做的导致核心模块和其他模块一定要一起加载呢?



    刚才Nick Wang提醒了,这和JIT有关。我认为应该是这样的,如果JIT执行代码的时候发现需要的类型没有加载,就去搜索程序集,然后自动加载进来。可以做个实验试试。

  42. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-16 23:58:00

    刚才Nick Wang提醒了,这和JIT有关。我认为应该是这样的,如果JIT执行代码的时候发现需要的类型没有加载,就去搜索程序集,然后自动加载进来。可以做个实验试试。

    >> 刚刚验证过,确实没错。



    Lib1和Lib2程序集只有在用到后,才被加载的。

    namespace ConTest
    {
    	class Program
    	{
    		public static void Main(string[] args)
    		{
    			AppDomain domain = AppDomain.CurrentDomain;
    			Console.WriteLine("Press any key to continue.");
    			
    			ConsoleKeyInfo key = Console.ReadKey(true);
    			while(key.Key != ConsoleKey.Escape)
    			{
    				Console.Clear();
    				
    				
    				switch(key.Key)
    				{
    					case ConsoleKey.A:
    						new Invoker1();
    						break;
    					case ConsoleKey.B:
    						new Invoker2();
    						break;
    					default:
    						break;
    				}
    				
    				foreach(Assembly assembly in domain.GetAssemblies())
    				{
    					Console.WriteLine(assembly.FullName);
    				}
    				
    				Console.WriteLine("Press any key to continue.");
    				key = Console.ReadKey(true);
    			}
    			
    		}
    	}
    }
    
    namespace ConTest
    {
    	/// <summary>
    	/// Description of Invoker1.
    	/// </summary>
    	public class Invoker1
    	{
    		public Invoker1()
    		{
    			(new Lib1.MyClass1()).SayHello();
    		}
    	}
    }
    
    
    namespace ConTest
    {
    	/// <summary>
    	/// Description of Invoker2.
    	/// </summary>
    	public class Invoker2
    	{
    		public Invoker2()
    		{
    			(new Lib2.MyClass2()).SayHello();
    		}
    	}
    }
    

  43. 老赵
    admin
    链接

    老赵 2009-10-17 00:04:00

    @道法自然
    话说,最好还是使用评论的代码插入功能来放代码吧。

  44. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-17 00:11:00

    @Jeffrey Zhao

    改了,有点偷懒,网速有点慢,那个框要几秒才弹出来。以后注意。

  45. 老赵
    admin
    链接

    老赵 2009-10-17 00:45:00

    果然“技术篇”比“吵架篇”要冷清不少。

  46. egmkang
    *.*.*.*
    链接

    egmkang 2009-10-17 00:47:00

    "我在日常开发中反射常用的几个环节,其实架构师架构系统反射等用得多,程序员日常开发里,其实不懂也没啥大不了的。"
    就这一句,直接雷倒n多用C/C++作为开发语言的架构师

  47. 小城故事
    *.*.*.*
    链接

    小城故事 2009-10-17 00:50:00

    有一种东西叫山寨,该说山寨好吗?不好吗?
    不管怎么说,个人钦佩老赵,也钦佩老吉。成功的道路有许多条,只要坚定不移地走下去,都能到达目的地。

  48. 周强
    *.*.*.*
    链接

    周强 2009-10-17 01:15:00

    Jeffrey Zhao:
    @ouzi2
    我反感对人不对事,我反感技术讨论时扯上“人品”等乱七八糟的东西。



    每当我们看的芙蓉婀娜的身姿,请问,我们究竟是恶心她的人品呢,还是恶心她做动作的“技术”不够好呢?

  49. 韦恩卑鄙
    *.*.*.*
    链接

    韦恩卑鄙 2009-10-17 07:15:00

    ---就算是有朋友认为的Remoting这个性能非常高的分布式调用方式,它的通信性能也远比反射要慢好几个数量级。假设一个反射消耗的时间是0.0001秒,那么它的确比直接调用消耗的0.0000001秒慢上一千倍,但是它还是可以在1秒钟执行1万次,不是吗?但是我们平时的SQL查询,有哪个可以如此高效?---


    个人认为
    remoting
    对于所有的对象使用反射来创建对象
    对于ISerilizable 外的对象 主要用了反射作为字段属性的读写
    从未摆脱反射的诅咒

  50. 韦恩卑鄙
    *.*.*.*
    链接

    韦恩卑鄙 2009-10-17 07:19:00

    Ivony...:

    横刀天笑:
    完全支持,顶,这才是反驳别人的正确方式,逐条驳斥。

    PS:我觉得你有一条理解错了吉日原文的意思(我猜想你很少做WinForm的应用)。
    比如,大一点的WinForm应用肯定会划分很多子模块。实际上只有使用到这个模块的功能(比如点击某个菜单)的时候才需要加载它。如果不用反射我们如何做到这点?
    一般做法肯定是,通过一个xml文件或者什么生成主界面的主菜单,当点击该菜单的时候,根据xml文件里设置的类型,加载相应的模块。
    (.Net本质论说的肯定是正确的,只是如果不用反射,这些模块就必须在编译时就引用、使用到)

    这几天一直在寻找关于WinForm架构的Best Practice。




    是不是理解为使用反射延迟编译而不是延迟加载。

    因为事实上CLR确实是用到时加载。



    的确 经常调用app domain那几个事件就有数了

  51. 韦恩卑鄙
    *.*.*.*
    链接

    韦恩卑鄙 2009-10-17 08:32:00

    @周强
    奇怪我不太反感。。。。

    doable.....是这么拼写么

  52. csd314[未注册用户]
    *.*.*.*
    链接

    csd314[未注册用户] 2009-10-17 09:49:00

    同意老赵的观点,搞技术就应该理智一点,跟人争论技术问题争的口水飞溅那是讨论跟切磋,但要是与人争论人品问题这样那就是泼妇吵架了,古人说“先做人、后做事”没有错,好的心态和交流精神对提升技术水平会有很大正面影响,而整天把心思放在勾心斗角上窝心的只有自己,也智慧浪费自己的时间
    我也经常关注很多技术博客,发现很多博主的写作方式有点信口开河、不负责任,正如老赵这里所写的几个例子,更可气的是某些博主对于别人的质疑和纠正以“SB”回应之,只能说为这种难有长进的同志感到悲哀
    老赵说的“吉日嘎拉”我不认识,但看了老赵的引用想来也不用去follow他的博客了,头一回听说代码生成器是最简单快速的方法,感觉有点可笑,自动生成代码与ORM框架不是一个层面的东西,好像不可比吧?就实际应用而言,用ORM当然更快,不过我很少用,不是不喜欢,而是感觉自己的水平比初学者也强不到哪里去,还没达到胸有成竹、炉火纯青的境界,所以尽可能多给自己留些手工写代码的机会,好让自己在写代码的过程中悟出更多东西
    不过建议老赵不用跟这种“代码小子”一般见识,老赵关注的是技术理论和架构策略、崇尚严谨客观的治学态度,“吉日嘎拉”这号人关注的是代码。有完善的理论基础支撑,代码实现轻而易举,如果只关注代码只会生活在无聊的复制粘贴中,开发的乐趣和激情就慢慢被消磨光了

  53. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-17 09:55:00

    周强:

    Jeffrey Zhao:
    @ouzi2
    我反感对人不对事,我反感技术讨论时扯上“人品”等乱七八糟的东西。



    每当我们看的芙蓉婀娜的身姿,请问,我们究竟是恶心她的人品呢,还是恶心她做动作的“技术”不够好呢?



    我都不讨厌,但也不喜欢。芙蓉就是自恋一点点而已了,起码不坏,比一些人确实强点。

  54. HBZ[未注册用户]
    *.*.*.*
    链接

    HBZ[未注册用户] 2009-10-17 10:18:00

    嘿嘿,我有个想法,把最近博客园的五四气氛和五四博贴弄到公司的Friday share(一个三地技术分享连线会议)上,看看能否捧出些许火花。对了还有前阵子前端社区的那个“炮轰征途“系列。

  55. heros
    *.*.*.*
    链接

    heros 2009-10-17 10:36:00

    Jeffrey Zhao:

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?


    我思考过了,应该是用户不点菜单是不会加载的才对,你是怎么做的导致核心模块和其他模块一定要一起加载呢?


    导航菜单自己思路是将MenuItem的层次关系和每个MenuItem对应的功能模块的MainWorkItem信息存储在数据库或xml文件中。点击菜单时用反射把程序集加进来。每个模块都实现共同的接口来提供模块主界面,供主模块来调用加载。如果有角色权限限制,也可以实现动态菜单功能的呈现。用cab实现这些要方便完善些。

  56. 北鸟教员heros
    *.*.*.*
    链接

    北鸟教员heros 2009-10-17 10:45:00

    改了昵称,怎么旧评论上的名子还是旧的名子?

  57. headchen
    *.*.*.*
    链接

    headchen 2009-10-17 10:45:00

    对于吉日说的反射使用的第一种场景,即“两个类相互引用”,我的理解,可能是表达有问题,大概是:“分布在两个程序集中的两个类相互引用”,这就造成了“程序集的循环引用”而带来了大问题。
    比如:EditorAttribute的设计中有构造函数:

    public EditorAttribute(string typeName,	string baseTypeName)
    
    


    就是用来解决这样的场景的,参数中的类用的是“名称”而不是Type,无疑内部就是用反射来实现的。这样当具体的EditorAttribute在别的程序集中时,避免了“程序集的循环引用”。因为你如果要为具体的某个类实现编辑器时,肯定要引用这个类的,而要把这个EditorAttribute“贴”到这个类时,就出现了吉日所说的“两个类相互引用”,如果这两个类在一个程序集,当然不存在任何问题,但分别于两个程序集时,就出现了这种场景。

    这种场景是否普遍,哪是另外一个话题了。

  58. Justice
    *.*.*.*
    链接

    Justice 2009-10-17 11:02:00

    Jeffrey Zhao:果然“技术篇”比“吵架篇”要冷清不少。


    是个人就都会吵架,但是技术不是人人都能谈的出来的(比如我)……

  59. 假正经哥哥
    *.*.*.*
    链接

    假正经哥哥 2009-10-17 11:02:00

    特地也去看看包的水文,还是老赵实在些。。
    包每次写文章都写不出个所以然来。。。要进修一下

  60. 老赵
    admin
    链接

    老赵 2009-10-17 11:16:00

    heros:
    导航菜单自己思路是将MenuItem的层次关系和每个MenuItem对应的功能模块的MainWorkItem信息存储在数据库或xml文件中。点击菜单时用反射把程序集加进来。每个模块都实现共同的接口来提供模块主界面,供主模块来调用加载。如果有角色权限限制,也可以实现动态菜单功能的呈现。用cab实现这些要方便完善些。


    不过你这个就是指动态的配置菜单项,和现在讨论的不是一回事情吧。
    现在就好比,直接在代码里静态地写死,那么如何让CLR延迟加载模块。
    我想了想,一般总是点了菜单项才加载的吧,因为JIT的单位是方法,而不是更大的范围。

  61. 老赵
    admin
    链接

    老赵 2009-10-17 11:17:00

    @headchen
    是啊,我的意思就是这个,如果两个程序集需要循环引用,那很可能是设计的问题,如果真需要循环引用,那么就让它们引用去吧。用反射不是解决问题的方式。

  62. Nick Wang (懒人王)
    *.*.*.*
    链接

    Nick Wang (懒人王) 2009-10-17 11:27:00

    Jeffrey Zhao:
    @headchen
    是啊,我的意思就是这个,如果两个程序集需要循环引用,那很可能是设计的问题,如果真需要循环引用,那么就让它们引用去吧。用反射不是解决问题的方式。


    如果真的需要循环引用就应该放在一个程序集里

  63. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-17 11:57:00

    Jeffrey Zhao:

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?


    我思考过了,应该是用户不点菜单是不会加载的才对,你是怎么做的导致核心模块和其他模块一定要一起加载呢?


    Sorry,是我描述错了。。。
    我想说的实际上是这个意思,对于多人开发一个大型的WinForm,每个功能模块与主界面应该是一种依赖倒置的关系,也就是子功能模块依赖启动模块,而不是启动模块依赖子功能模块,所以对于每个功能模块的菜单我们不应该直接在程序主界面里写死,而应该通过一种机制,自动的搜索指定目录下的配置文件,以这种形式生成菜单,也就是子功能模块自己负责自己的菜单。因为如果不按照这种方式,添加菜单部分的代码就有可能频繁的改动(也就是主界面有可能频繁改动,多人编辑)。不知道我描述清楚没?实际上我想说的就是一种Plugin的方式,在大点WinForm应用里必须采用。如果不采用这种方式,主模块就必须引用几十个子模块(当然,我知道CLR是按需加载的)。这样主模块也“不稳定”,不是说运行不稳定。

  64. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-17 12:00:00

    PS:虽然CLR是按需加载的,按理说多引用模块和少引用模块性能应该是差不多的。但是我不知道曾经在哪里看过一篇文章说:尽量少的引用不必要的模块。说这个对性能有影响,但是我没有考证。

  65. Fred_Xu
    *.*.*.*
    链接

    Fred_Xu 2009-10-17 12:05:00

    程序员也是分层次的,有的很菜有的很牛有的很中庸,这些不同层次写出来的博文质量肯定也不相同,认识上也是不同的。“吉日嘎啦”的水平我想也不是很菜鸟的那种,但至少他写博文分享了经验和自己主观认识,这点是没有错的。博客园需要每个人来写博客分享。

    但是问题在于“吉日嘎啦”太过于滥用首页精华区了,有点儿自认为自己很牛逼,这种态度我个人不是很欣赏。其实吧,我也不是很想看到大家发起口水战的,更希望能交流技术上的问题,这对于每个人新手、中等水平的、牛人起到一个学习认识的作用。

    老赵嘛,肯定大牛人了,我看他的博文不是一股脑写出来的,肯定是经过很多思考和认识才发表出来的,质量很高。

    就我现在的水平,相比吉日嘎啦和老赵还有很多差距,需要更多时间去学习。我自己认为自认为自己很牛,发表博文质量不高,每次都在首页精华区会误人子弟。

    首页精华区应该是牛人博文、原创博文、开源代码发布博文、技术讨论这类的文章,博客园的管理员应该对其审核。否则有可能会误人子弟的。

  66. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-17 12:10:00

    再留一条
    ----------------------------------------------------
    突然发现,我的评论偏离了文中的主线,我说的应该是一个设计的问题。老赵原文中对吉日的评论没错。。。即使不用反射也不会造成主程序启动时,加载一堆的模块。
    ----------------------------------------------------
    Sorry,我这几天一直在做一个框架的设计,原先采用的是SharpDevelop的插件机制,但是这个东东太重型了,要重新设计个,又要多人开发时互不影响,主程序框架必须稳定,确定后就不再修改。所以满脑子这个。。。

  67. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-17 12:17:00

    横刀天笑:
    再留一条
    ----------------------------------------------------
    突然发现,我的评论偏离了文中的主线,我说的应该是一个设计的问题。老赵原文中对吉日的评论没错。。。即使不用反射也不会造成主程序启动时,加载一堆的模块。
    ----------------------------------------------------
    Sorry,我这几天一直在做一个框架的设计,原先采用的是SharpDevelop的插件机制,但是这个东东太重型了,要重新设计个,又要多人开发时互不影响,主程序框架必须稳定,确定后就不再修改。所以满脑子这个。。。



    SD的插件机制有点轻量级了,可以试着看一下OSGi。OSGi的关键点是:1 支持SOA模块设计; 2 完全的模块化和插件化。

    不过在.NET中,目前还没有完全兼容OSGi规范的FW,目前我正在实现OSGi.NET框架,但是还没有重构好,估计年底可以出来。

  68. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-17 12:19:00

    @道法自然
    我想还“清凉”一点,只是简单的包装一下反射就行的~~~

  69. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-17 12:22:00

    横刀天笑:PS:虽然CLR是按需加载的,按理说多引用模块和少引用模块性能应该是差不多的。但是我不知道曾经在哪里看过一篇文章说:尽量少的引用不必要的模块。说这个对性能有影响,但是我没有考证。



    在我的实验中已经验证了这个理。程序启动后,执行Main方法,它将开始加载该类型相关的程序集,其中有两个类Invoke1和Invoke2分别用于调用另外2个程序集的类的方法。由于Invoke1和Invoke2都属于同一程序集,不需要加载。当执行new Invoke1()时,这个类引用了Lib1程序集,JIT便自动开始搜索Invoke1这个类构造器需要的类型,然后按需加载。

    少引用不必要的模块确实也是有道理的,如果一个类引用了另一个模块的话,在加载该类的时候,会同时加载不必要模块。

  70. 道法自然
    *.*.*.*
    链接

    道法自然 2009-10-17 12:29:00

    横刀天笑:
    @道法自然
    我想还“清凉”一点,只是简单的包装一下反射就行的~~~



    明白,那按需而行就可以了。这些基础的东西随便用都可以达到目的了。

  71. headchen
    *.*.*.*
    链接

    headchen 2009-10-17 12:37:00

    Jeffrey Zhao:
    @headchen
    是啊,我的意思就是这个,如果两个程序集需要循环引用,那很可能是设计的问题,如果真需要循环引用,那么就让它们引用去吧。用反射不是解决问题的方式。



    可能我说的太委婉了。任何设计均是各种利弊均衡的结果,比如我举的例子就是.Net Framework中的一种设计。
    我说的真正意思是:“这种需求确实存在,有一定的合理性,但不一定具有普遍性。”

  72. gihelo
    *.*.*.*
    链接

    gihelo 2009-10-17 12:58:00

    恩,现在也的确是要净化一下风气了,拜X日这种不怎么负责的博主所赐,现在的新人的确是被误导的很严重啊。

    linq2sql = linq,
    3层 = 对象化编程,
    mvc,ajax = 高级技术
    aop = 高级架构
    数据库索引 = 百万数量级
    xml,ini = 一个硬盘文件
    orm = 啥也不用写,拖过来就用
    模板引擎 = 换肤
    div+css = web2.0
    ----------------

    类似这种以偏概全的误导,实在是可怕啊。

  73. 北鸟教员heros
    *.*.*.*
    链接

    北鸟教员heros 2009-10-17 13:13:00

    Jeffrey Zhao:
    不过你这个就是指动态的配置菜单项,和现在讨论的不是一回事情吧。
    现在就好比,直接在代码里静态地写死,那么如何让CLR延迟加载模块。
    我想了想,一般总是点了菜单项才加载的吧,因为JIT的单位是方法,而不是更大的范围。


    我理解横刀天笑评论理解成了如何构建这样的应用了。就是你说的这样,clr按需加载的,硬编码的也没问题,不执行不加载。但调试的时候似乎是当前程序集的直接引用会全加载,执行过程中还会按需加载新的。

  74. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-10-17 14:19:00

    @北鸟教员heros
    请看我这篇博客:http://www.cnblogs.com/yuyijq/archive/2009/10/17/1585041.html

  75. 茶杯
    *.*.*.*
    链接

    茶杯 2009-10-17 15:15:00

    老赵的文章相当的精辟啊。分析的有水准

  76. 极品拖拉机
    *.*.*.*
    链接

    极品拖拉机 2009-10-17 20:13:00

    老赵。能不能把你字体搞大点的啊
    物品19寸的显示器都看不清楚

  77. 青林一霸
    *.*.*.*
    链接

    青林一霸 2009-10-17 22:20:00

    如果没有你们这些争论,我们这些门外汉看什么啊?呵呵,很好,两边学东西

  78. coollzh
    *.*.*.*
    链接

    coollzh 2009-10-17 23:03:00

    "而NHibernate的首席开发人员Oren Eini还在他的一次NDC的演讲中认为不该为数据访问层花费任何时间,应该把时间放在和业务相关的代码上面,否则就是浪费金钱。“

    ORM确实能提高开发效率,不过这些xml配置的维护是个噩梦,特别是多人开发、开发,程序发布分离的这种运维模式。

    老实说我从没有在比较正式的大型的项目中使用ORM,就有一个用了IBatis.NET,后来还换回来了。是不是有点落伍了,呵呵

    我大概算了一下,一个中型的电子商户网站类的应用,数据访问层的代码基本上在整个项目开发周期的1/5-1/10.不是瓶颈,当然越快越好了:)

  79. Arthas-Cui
    *.*.*.*
    链接

    Arthas-Cui 2009-10-18 10:10:00

    其实即使是“反射慢”这个说法似乎也被理解过分了。

    我感觉软件里很多道理都会被大家过分理解。

    比如反射的速度, 我没有具体的权威理论证明,
    但是实际用的时候测过一些方法的速度。

    如果拿到MethodInfo进行Invoke, 速度和直接调差不多。
    只有用InvokeMember那类方法的时候才会慢。
    因为涉及到要找到对应的MethodInfo的问题。

    不晓得理解对不对。

    总之从这个角度来说, 反射稍稍优化优化, 一点都不慢的。

  80. 老赵
    admin
    链接

    老赵 2009-10-18 11:38:00

    Arthas-Cui:
    如果拿到MethodInfo进行Invoke, 速度和直接调差不多。
    只有用InvokeMember那类方法的时候才会慢。
    因为涉及到要找到对应的MethodInfo的问题。


    拿到MethodInfo进行Invoke,比直接调用还是差很多的,这里有性能评测。
    http://www.cnblogs.com/JeffreyZhao/archive/2009/01/31/Fast-Reflection-Library.html

  81. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-10-18 18:52:00

    横刀天笑:

    Jeffrey Zhao:

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?


    我思考过了,应该是用户不点菜单是不会加载的才对,你是怎么做的导致核心模块和其他模块一定要一起加载呢?


    Sorry,是我描述错了。。。
    我想说的实际上是这个意思,对于多人开发一个大型的WinForm,每个功能模块与主界面...




    So,我一开始就说了你这是延迟编译,换言之子模块编译在主模块之后。

    或者你会想说依赖倒置才是问题的本质,但我却不觉得,因为依赖倒置从实现上并不是非反射不可的,只是说反射是一种很好的实现。

  82. 妖居
    *.*.*.*
    链接

    妖居 2009-10-19 10:09:00

    老赵能不能趁着这个机会说一下反射和4.0里面DLR的关系。感觉DLR有点反射的味道,也有点VB.NET里面延迟绑定的味道。到底有什么关系,又有什么不同呢?

  83. virus
    *.*.*.*
    链接

    virus 2009-10-21 09:00:00

    任何美丽的接口后面都有丑陋的实现”,美妙的接口,好用API,它的目的就是帮你在项目中避免“亲自”操作这些丑陋的内容。

    经典了,同意

    看不见的不见得美丽,看见的不见得不美丽

  84. thk_xing
    *.*.*.*
    链接

    thk_xing 2009-10-22 16:31:00

    “他对于技术的态度,我还是不喜欢”,老赵一语道破天机。。。

  85. 垃圾呆
    *.*.*.*
    链接

    垃圾呆 2009-11-23 12:58:00

     至于代码生成器,的确好用,我也推荐多用
    能不能给点资源链接之类的,刚毕业工作直接将就是用EF做项目,感觉还是想试试代码生成器,但周围基本又没人用~

  86. mysun
    *.*.*.*
    链接

    mysun 2009-11-24 09:42:00

    这么多人在讨论,从头到尾看了一遍,有所收获,我经常会和朋友,同事拿某一技术问题进行讨论,有时争的脸 红脖子粗,但我觉得这样有好处,只有这样你才去思考,才去想,不过进行人身攻击就不对了,中国软件技术要进步,不争不论怎么进步,不过要文明上网,呵呵

  87. mysun
    *.*.*.*
    链接

    mysun 2009-11-24 09:46:00

    @道法自然

    横刀天笑:
    @Ivony...
    您说的CLR用到时加载我举双手同意。但这里不是这个问题。
    比如,你思考这样一个应用:
    该应用有10个主菜单,每个主菜单下有5个子菜单,每个菜单关联一个功能(独立模块)。那么就有50个独立模块,如何保证应用启动时只启动核心模块,而不加载这50个模块?



    这种想法实在不敢苟同,clr如果是这种机质进行加载的话,那真的完了。

  88. 横刀天笑
    *.*.*.*
    链接

    横刀天笑 2009-11-24 14:07:00

    @mysun
    不好意思啊,我当时脑袋秀逗了。。。。说出这么“无知”的话来。。。惭愧不已。。。我后来也写了一篇文章重新澄清。。。

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我