Hello World
Spiga

老赵谈IL(4):什么时候应该学IL,该怎么学IL

2009-12-25 00:08 by 老赵, 12029 visits

又是一个拖了半年的系列,可能是前几篇主要以事实为准,举例子的文章总是比较容易写的,因此十分顺畅。而最后一篇打算做一个总结,以讲道理为主——却发现该将的似乎都已经讲完了。不过做事要有始有终,该完成的也必须要完成。那么现在就来谈谈我的一些个人看法:什么时候应该学IL,以及应该怎么学IL。

对了,先表个态,我个人并支持普通程序员学习IL——至于什么是“普通”,什么叫做“学习”我们再慢慢谈。

经常听到有朋友有人说:如果要成为一个优秀的.NET程序员,那么IL很重要,一定要学习。这时候我经常会问一句“为什么”,得到的答复往往是“IL比较接近底层”。不过在我看来,“底层”只是IL本身的特性,并不足以证明“IL是高级程序员的必知必会”。IL的确比C#等高级语言来的所谓“底层”,但是IL本身其实也是一种高级抽象,它所能表现出来的几乎所有东西,都可以从C#等高级语言中获取到,而我们平时所了解到的如“装箱”,“引用类型和值类型的分配方式”,“垃圾收集”都属于CLR的范畴,您可以从书中看到或听人讲起,但是无法从IL上看出来

当然,无论怎么说IL总是相对较为“底层”的东西,但是“底层”就应该学习吗?从不同层次可以获得不同信息,我们追求“底层”的目的肯定也不是“底层”这两个字,而是一种收获。所有人的时间或精力都是宝贵的,而对于一个优秀的程序员来说,知道了解自身需要什么,然后能够选择一个合理的层次进入,并得到更好的收益,这本身也是一种能力——而且可以说是必须的能力。这种能力不光是体现在有选择性的“学习”上,而可以体现在更多方面,因为几乎做任何一件事情都有多种方式,我们要选择最合适的。

方法,很重要。

学习IL的另一个重要“原因”,可能是有些朋友认为学习IL对于优化.NET程序性能有帮助,对于这个问题在之前的文章中也有过讨论,这次再拿出来一谈。性能优化是最需要“方法”的工作之一,如果方法不对,不仅仅是工作效率的问题,甚至很难得到正确的结果。IL和普通高级语言的代码一样,是一种静态的事物,您就算对它了解地再透彻,您也只能“阅读”它。而对于性能优化来说,要做的事情有很多,“阅读代码”在其中的重要性其实并不高——而且它也最容易误入歧途的一种。如果要进行性能优化,首先要进行的其实是“发现需要优化的地方”。徐宥写过这样一个八卦

话说当年在贝尔实验室,一群工程师围着一个巨慢无比的小型机发呆。为啥呢,因为他们觉得这个机器太慢了。什么超频,液氮等技术都用了,这个小型机还是比不上实验室新买的一台桌上计算机。这些家伙很不爽,于是准备去优化这个机器上的操作系统。他们也不管三七二十一,就去看究竟那个进程占用CPU时间最长,然后就集中优化这个进程。他们希望这样把每个程序都优化到特别高效,机器就相对快了。于是,他们终于捕捉到一个平时居然占50% CPU的进程,而且这个进程只有大约20K的代码。他们高兴死了,立即挽起袖子敲键盘,愣是把一个20K的C语言变成了快5倍的汇编。这时候他们把此进程放到机器上这么一实验,发现居然整体效率没变化。百思不得其解的情况下他们去请教其他牛人。那个牛人就说了一句话:你们优化的进程,叫做System Idle。

无论这个八卦是否存在“艺术加工”,但都至少说明一个问题,就是如果没有经过合适的Profiling,没有找到性能的问题所在,优化是几乎不会有效果的。因此,我们一直说要把代码写的易于理解,说make clean code fast远比make fast code clean要容易,都是同样的道理,因为代码清晰,我们可以找出其性能瓶颈,然后有针对性地加以优化——那么,了解IL对此会有帮助吗?IL虽然并不难懂(稍后会谈到),但也比如C#代码要“间接”很多——试想,如果您使用阅读IL的方式来了解字符串连接的实现细节会是什么情况呢?

因为程序是动态的,动态的事情要用“动态的方式”地决定,也就是Profiling。而即便是最最普通的Profiling方式,如使用CodeTimer来统计时间,也比“阅读代码”要靠谱许多,因为它可以直接反应出不同实现方式之间运行时间的区别——而不是靠猜测。事实上您也可以发现,我在研究性能问题的时候,使用的最多的还是CodeTimer(如泛型问题并发缓存容器字符串连接)。的确,CodeTimer得到的只是“表象”,因此发现性能瓶颈可能还需要依赖Profiler——这也是我为什么在这个问题上尝试半天的原因。有了Profiler之后,发现性能的Hot Path便有更多依据了。

方法,很重要。

再次表达观点:我认为,对于一个“普通”的.NET程序员来说,是需要去“学习”IL的。这里的“普通”二字是针对“工作内容”,而不是“人员水平”。也就是说,和“普通程序员”相对的是“工作内容特别的程序员”而不是“高级程序员”。“特殊”是指您的工作需要“直接”用到IL,例如您如果想要写一个.NET上的新语言,就必须了解IL,了解怎样使用IL写程序。而“直接”二字自然是和“间接”二字对应,或者说您的工作中会“顺便”用到IL——例如,您像我一样想要写一个延迟加载类库,或者为NHibernate实现个通用的UserType支持——在这种情况您可能也并不需要花功夫去学它。事实上,按照我的分类方式,我也是个普通程序员,所以我没有学IL,我很难看懂复杂的IL代码,更不会用IL写程序,但这并不影响我完成一些简单的IL相关工作——这并不矛盾。

为什么这么说呢?因为IL和C#这样的高级语言实在太接近了。IL几乎只是C#的另一种表现形式,它和C#一样,都几乎直接表现出.NET中定义的各种概念:泛型、数组、类、接口、继承、异常……甚至连部分关键字都一样。还有相当重要的一点,它们都是命令式的语言,因此.NET Reflector可以将其“还原”成C#代码,因为在这个过程中实在没有丢失太多信息。但是,如果想要把IL还原成F#,这就非常困难了,因为F#和IL无法做到十分对应。因此,您在通过C#学习.NET时,已经在不断降低IL的门槛了。最后您会发现,IL真不是什么特别的东西。

于是,在用到Emit的时候,您就可以先写一些C#目标代码并编译成程序集,然后用.NET Reflector将其反编译成IL,一条一条指令地“抄”至程序中——甚至现在已经有了插件来生成这些Emit代码。同样,只要有些耐心和细心,修改个程序集可能也只是“写C#”,“反编译”,“复制/粘贴”的过程而已。

很多时候,IL也只是被“神化”了。因此会有朋友觉得,了解IL的就是高手,要成为高手必须学习IL——其实IL和水平高低的关系并不大。多说一句,即便是所谓“底层工作者”,这也是在不同抽象上办事,并不代表他们一定就是牛人。我之前谈的很多东西,其实也是想打破这个“IL神话”罢了。有时候我也纳闷,为什么Java平台上学习Byte Code或JVM的“氛围”就远不如.NET平台上学习IL和CLR呢?

当然,如果您真心希望,您感兴趣,自然可以学习IL——多了解一些总是好的。我建议,如果您真要学习IL,可以先去学习一些汇编——这么说似乎也不够确切,因为我始终认为它们的可比性并不大——只是从“表现形式”上来说,IL和汇编略有相似(例如逻辑跳转方面)。您可以先看看《深入理解计算机系统》这本书,它讲的不是IL,它讲的是“计算机系统”。在学习过程中会涉及到一些汇编——甚至您可以直接翻到对应章节学习这部分内容。您无需“学完”,只需要大概了解一下,再配合C#编程经验,就会发现IL其实“真的很直观”,此时您可能已经不太会去找一本讲IL的书去特意学习IL编程了。

嗯,“找一本讲IL的书去特意学习IL编程”,这就是我在文章开始提到的学习方式——我推荐这种做法。

相关文章

Creative Commons License

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

Add your comment

55 条回复

  1. tshao[未注册用户]
    *.*.*.*
    链接

    tshao[未注册用户] 2009-12-25 00:12:00

    支持老赵、圣诞快乐!

  2. 老赵
    admin
    链接

    老赵 2009-12-25 00:29:00

    @tshao
    谢谢

  3. 老赵
    admin
    链接

    老赵 2009-12-25 00:32:00

    这个系列终于写完了……呼……

  4. 伊牛娃
    *.*.*.*
    链接

    伊牛娃 2009-12-25 00:38:00

    老赵,早点休息

    圣诞快乐

  5. liuyong
    *.*.*.*
    链接

    liuyong 2009-12-25 00:44:00

    圣诞快乐!

  6. 老赵
    admin
    链接

    老赵 2009-12-25 00:59:00

    @DeathKnight
    说的好啊

  7. DeathKnight
    *.*.*.*
    链接

    DeathKnight 2009-12-25 00:59:00

    其实我觉得这个现象跟教育方式有关系 太多老师喜欢显摆 告诉大家我用的东西多么复杂你们看不懂 我就是牛 所以导致不少学生也留下了这种追求复杂和晦涩的心结 而不是去寻求清晰的思路 事实上某种程度上说简洁的东西更难得到

    学习方式和思考方式很重要 顶一下~

  8. xiaotie
    *.*.*.*
    链接

    xiaotie 2009-12-25 01:05:00

    哈哈。那个八卦太损人了!

  9. 徐少侠
    *.*.*.*
    链接

    徐少侠 2009-12-25 07:30:00



    关于“普通”程序员和“特殊”程序员的论述和我的一贯思想非常一致
    我也是这么看问题的

    会底层多数时候并不代表资深和高级
    只是工作领域不同而已

    这行业里误导的东西不少啊

    牛人一定会知道底层的东西,知道底层东西的不一定是牛人
    优秀的程序员多数都会IL,会IL不一定是优秀的程序员

    绕口哦。呵呵

  10. liulun
    *.*.*.*
    链接

    liulun 2009-12-25 08:26:00

    @徐少侠
    "牛人一定会知道底层的东西,知道底层东西的不一定是牛人"

    如果说一个还不是牛人的人,想变成牛人,那他该什么时候去学底层呢?



  11. Jerry Chou
    *.*.*.*
    链接

    Jerry Chou 2009-12-25 08:26:00

    "而对于一个优秀的程序员来说,知道了解自身需要什么,然后能够选择一个合理的层次进入,并得到更好的收益,这本身也是一种能力——而且可以说是必须的能力。"

    老赵说的这句话体验比较深,什么看到了,都感兴趣。但越学越会取舍。

    不过,这对一个“普通”程序员来说,有一点不好的是:找工作的时候,老是被别人问住。
    比如,你现在申请一个高级工程师的职位,问你了解IL嘛?
    你该怎么回答呢?

    呵呵,老赵的文章“通常”是看不懂的,唯这篇,体会较深。

    圣诞快乐~

  12. 红泥
    *.*.*.*
    链接

    红泥 2009-12-25 08:38:00

    看了《深入理解计算机系统》一些章节后 俺信老赵了

  13. 老赵
    admin
    链接

    老赵 2009-12-25 09:09:00

    liulun:
    @徐少侠
    "牛人一定会知道底层的东西,知道底层东西的不一定是牛人"

    如果说一个还不是牛人的人,想变成牛人,那他该什么时候去学底层呢?


    其实我觉得你学习过程中必然会涉及一些这方面的东西,不一定需要特定去学……还有就是如果你感觉遇到瓶颈了……
    当然,如果你说要学习CSAPP上面的东西,我肯定支持,但是学习IL……我觉得没有必要。

  14. FLY FREE
    *.*.*.*
    链接

    FLY FREE 2009-12-25 09:20:00

    每天多看一点。。多学一点。。

  15. 23123[未注册用户]
    *.*.*.*
    链接

    23123[未注册用户] 2009-12-25 09:26:00

    一大清早上博客园马上就被"老赵"了....看来我得好好想下我每天应该收获一些什么

  16. Dr.Edison
    *.*.*.*
    链接

    Dr.Edison 2009-12-25 09:33:00

    支持 老赵 我就买了本讲IL的书 结果只看了里面的.net 基础 和OOP的简单部分 后面的IL一点都看不下去了

  17. Dr.Edison
    *.*.*.*
    链接

    Dr.Edison 2009-12-25 09:34:00

    附加一句 真正底层 汇编 C都比那个要底层多了 还是看看c 或者汇编才好!~

  18. 老赵
    admin
    链接

    老赵 2009-12-25 09:36:00

    Jerry Chou:
    不过,这对一个“普通”程序员来说,有一点不好的是:找工作的时候,老是被别人问住。
    比如,你现在申请一个高级工程师的职位,问你了解IL嘛?
    你该怎么回答呢?


    “了解一些,不熟,不如我们来探讨一下?”

  19. 老赵
    admin
    链接

    老赵 2009-12-25 09:36:00

    @Dr.Edison
    不过我只是说“没必要看”,没说“看不下去”是正常的……

  20. ㊣孤叶
    *.*.*.*
    链接

    ㊣孤叶 2009-12-25 09:59:00

    DG

  21. zsea
    *.*.*.*
    链接

    zsea 2009-12-25 10:03:00

    我挺喜欢老赵的文章的

  22. Seasun海豚
    *.*.*.*
    链接

    Seasun海豚 2009-12-25 10:06:00

    看你的文章对我很受益。

  23. DiggingDeeply
    *.*.*.*
    链接

    DiggingDeeply 2009-12-25 10:29:00

    这个学不学看个人喜好,懂了IL基本能明白CLR是怎么解释上层代码的。
    IL是高级语言的语言,倒是没什么神秘的。

  24. 梦幻天涯
    *.*.*.*
    链接

    梦幻天涯 2009-12-25 10:49:00

    以前为了实现动态的计算条件,没办法就用了一次Emit,平时还真用不到,后来有了表达式树后,觉得以前写的东西也没必要用IL了。

    有些东西知道决不是坏事,鬼知道哪一天用到呢?

  25. DiggingDeeply
    *.*.*.*
    链接

    DiggingDeeply 2009-12-25 10:50:00

    @Jerry Chou
    难者不会,会者不难。
    多看书

  26. 老赵
    admin
    链接

    老赵 2009-12-25 10:52:00

    @梦幻天涯
    知道的多一些总是好的,只是就看抱有什么态度去学IL了。
    学习IL不是问题,有问题的是觉得“不知道IL算不上高手”这种想法。
    哦,还有,就是对IL感到害怕,觉得肯定接受不了,也是不对的。

  27. winter-cn
    *.*.*.*
    链接

    winter-cn 2009-12-25 11:07:00

    与其把精力花在IL上 不如多了解CLI

  28. winter-cn
    *.*.*.*
    链接

    winter-cn 2009-12-25 11:13:00

    Jeffrey Zhao:

    Jerry Chou:
    不过,这对一个“普通”程序员来说,有一点不好的是:找工作的时候,老是被别人问住。
    比如,你现在申请一个高级工程师的职位,问你了解IL嘛?
    你该怎么回答呢?


    “了解一些,不熟,不如我们来探讨一下?”


    "不会IL 平时工作也用不着 但我很了解CLR哦~ 要说IL我也不算完全不会 我曾经写过一门灰常简单的语言到IL的Compiler 所以哩 多少知道一点点啦"

  29. 韦恩卑鄙 alias:v-zhewg
    *.*.*.*
    链接

    韦恩卑鄙 alias:v-zhewg 2009-12-25 11:45:00

    winter-cn:

    Jeffrey Zhao:

    Jerry Chou:
    不过,这对一个“普通”程序员来说,有一点不好的是:找工作的时候,老是被别人问住。
    比如,你现在申请一个高级工程师的职位,问你了解IL嘛?
    你该怎么回答呢?


    “了解一些,不熟,不如我们来探讨一下?”


    "不会IL 平时工作也用不着 但我很了解CLR哦~ 要说IL我也不算完全不会 我曾经写过一门灰常简单的语言到IL的Compiler 所以哩 多少知道一点点啦"


    我都简单的说:平时用reflector 对比下 复制粘贴。
    面试不是为了彼此显示虚假实力的咋呼比赛 不但要体现出真实水平 还要表现诚恳的态度和平易近人的沟通能力。 面试你的人不但是把关技术 还要考虑和你一起工作的成本和风险,说过了不好。

  30. winter-cn
    *.*.*.*
    链接

    winter-cn 2009-12-25 12:17:00

    @韦恩卑鄙 alias:v-zhewg
    当然真面试的时候不用说得这么90后啦
    而且我是真的写过BF到IL的Compiler 也不算虚假 哈哈

    总之面试这回事 未必人家问什么就答什么 问题是你了解面试官意图的一个窗口

    人家问IL未必是期望你会IL 他多半是想了解你对CLR的熟悉程度 借机会谈谈做过的相关的小玩意就行了

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

    kisskiki[未注册用户] 2009-12-25 12:47:00

    大多数人应该不会学这个除非工作所致,不过有多余精力或者时间也许会有人来弄这个

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

    小城故事 2009-12-25 13:36:00

    “对于一个优秀的程序员来说,知道了解自身需要什么,然后能够选择一个合理的层次进入,并得到更好的收益,这本身也是一种能力——而且可以说是必须的能力。”

    这就是学习的真正奥义-学以致用,在应试教育环境下长大的我们要找回这一真谛。授人鱼不如授人以渔,老赵是很好的老师。

    个人觉得,老赵应该去大公司,比如微软什么的,作研究院院长,就是李开复以前的职位。

  33. toEverybody
    *.*.*.*
    链接

    toEverybody 2009-12-25 14:55:00

    对了,先表个态,我个人并不支持普通程序员学习IL——至于什么是“普通”,什么叫做“学习”我们再慢慢谈。
    ---------中国的程序有90%是普通的程序员,它们以熟练开发Asp.net,Winform为荣,它们却不知
    你所需要的开发功能要等别人来添加.

    当然,无论怎么说IL总是相对较为“底层”的东西,但是“底层”就应该学习吗?从不同层次可以获得不同信息,我们追求“底层”的目的肯定也不是“底层”这两个字,而是一种收获。
    --------同意你的观点.。底层我把它叫作可控的,可变的计算机软件部件.

    IL和普通高级语言的代码一样,是一种静态的事物,您就算对它了解地再透彻,您也只能“阅读”它。而对于性能优化来说,要做的事情有很多,
    -------C#只提供代码层的优化.你无法从底层来控制C#代码的运行方式.对于性能关键的地方
    C#就显得无法进行所谓的优化了.因为它就是这个速度(当然象我们很多的同志说的一样,要编译编译再编译,然后执行,当然要慢一些),我们对于软件关键的地方我们用C或汇编, 或象Delphi,C++
    一样嵌入汇编让软件运行的象飞一样.C#作不到,因为它定位在应用层面的,叫高级语言

    为什么这么说呢?因为IL和C#这样的高级语言实在太接近了。IL几乎只是C#的另一种表现形式
    -------IL确实是C#编译为解决某一问题而产生的有规律的"乱码";我一定这么认为

  34. 老赵
    admin
    链接

    老赵 2009-12-25 15:12:00

    @toEverybody
    大部分语言都不能嵌入ASM,如果你以此作为衡量标准,我的确很能理解你为什么认为C++等语言要强大的多阿,呵呵。

  35. 装配脑袋
    *.*.*.*
    链接

    装配脑袋 2009-12-25 15:24:00

    IL比C#限制更少,更朴素。有些人C#写多了,就以为IL也是那个样子。比如不知道indexer其实是属性,要用反射访问的时候不知道应该去GetProperty之类的……要说这种其实还是能举出不少来的。。

  36. 老赵
    admin
    链接

    老赵 2009-12-25 15:28:00

    @装配脑袋
    嗯嗯,其实语言都只是使用了IL的一个子集,IL总归会多一些的。
    其实脑袋说的东西,也还是看看IL是什么样子就可以啦,我就是感觉专门学习IL必要性不大。

  37. 装配脑袋
    *.*.*.*
    链接

    装配脑袋 2009-12-25 15:34:00

    想当年。。。没有Reflector的时候……

  38. 老赵
    admin
    链接

    老赵 2009-12-25 15:36:00

    @装配脑袋
    话说.NET Reflector真是厉害……

  39. 张荣华
    *.*.*.*
    链接

    张荣华 2009-12-25 15:48:00

    老赵多次提到“深入理解计算机系统”这本书,看来我也去买一本了。

  40. Yankee
    *.*.*.*
    链接

    Yankee 2009-12-25 15:53:00

    留个脚印...

  41. skyaspnet
    *.*.*.*
    链接

    skyaspnet 2009-12-25 16:33:00

    @徐少侠
    您好,在某个领域的牛人是否一定要精通底层?例如WEB架构师等岗位,谢谢,祝大家圣诞快乐!

  42. toEverybody
    *.*.*.*
    链接

    toEverybody 2009-12-25 16:54:00

    skyaspnet:
    @徐少侠
    您好,在某个领域的牛人是否一定要精通底层?例如WEB架构师等岗位,谢谢,祝大家圣诞快乐!


    我认为不需要,你就算了解了底层,也用C#控制不了底层

  43. 老赵
    admin
    链接

    老赵 2009-12-25 16:56:00

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

    道法自然 2009-12-25 16:59:00

    时间少,事情多,把时间花在目前对自己而言最需要的地方就对了。

  45. airy
    *.*.*.*
    链接

    airy 2009-12-25 18:39:00

    DeathKnight:
    其实我觉得这个现象跟教育方式有关系 太多老师喜欢显摆 告诉大家我用的东西多么复杂你们看不懂 我就是牛 所以导致不少学生也留下了这种追求复杂和晦涩的心结 而不是去寻求清晰的思路 事实上某种程度上说简洁的东西更难得到

    学习方式和思考方式很重要 顶一下~


    严重同意

  46. RednaxelaFX
    *.*.*.*
    链接

    RednaxelaFX 2009-12-25 20:14:00

    well……什么东西要学不学都是浮云撒,如果不拿来用的话。

    Jeffrey Zhao:
    很多时候,IL也只是被“神化”了。因此会有朋友觉得,了解IL的就是高手,要成为高手必须学习IL——其实IL和水平高低的关系并不大。多说一句,即便是所谓“底层工作者”,这也是在不同抽象上办事,并不代表他们一定就是牛人。我之前谈的很多东西,其实也是想打破这个“IL神话”罢了。有时候我也纳闷,为什么Java平台上学习Byte Code或JVM的“氛围”就远不如.NET平台上学习IL和CLR呢?


    其实神化的IL是怎样的……?老赵来个链接看看吹嘘IL的帖子是怎样的~

    老赵要说Java平台上学习bytecode的人不如.NET上学习IL的氛围浓,其实我也没太觉得.NET上学IL的氛围很重嘛。再说,许多人(包括我)都是稍微看看IL,够用就OK,要真“学习”的话恐怕还不能止于此。如果Java平台上学习bytecode的氛围真的较淡,Java标准库里没有对生成bytecode有直接支持或许也是原因之一。相比之下,.NET的标准库里有SRE,想用直接就拿来用了,也不需要第三方库/工具。Java平台上如果不想手写字节的话就还是得靠第三方库了,例如objectweb的ASM(但也不怎么方便……)

    我还是觉得懂点IL对C#程序员来说是有好处的……至少用来理解C#的语义挺有效的。要写高动态性+高效的程序时IL也会是个帮手。看DLR是如何用SRE来生成inline cache...

  47. 老赵
    admin
    链接

    老赵 2009-12-25 20:20:00

    @RednaxelaFX
    不是吹嘘IL,而是觉得“不到长城非好汉”,例子分散在各处,没有某个帖子……当然学IL肯定是有用的了,我的意思是关键看有多少效果。
    至于DLR如何用SRE来生成inline cache……我猜主要靠具体的优化方法吧,我觉得和IL使用应该没有太大关系……我的意思是,DLR这个方法,如果要用在JVM上是否可以呢?
    当然,如果DLR这个方法是不是利用了IL的特性……那对IL的了解就是关键了,hoho

  48. RednaxelaFX
    *.*.*.*
    链接

    RednaxelaFX 2009-12-25 21:00:00

    @Jeffrey Zhao
    不是说利用了IL的什么神奇特性,而是处理的程序行为非常动态,不靠IL就得靠纯反射来做了,开销太大。
    在JVM上当然也可以通过生成字节码来实现inline cache,例如说JRuby当前的实现就是这样的。这帖提到的DLR callsite的缓存机制,最初的一级缓存是单态内联缓存,在一定条件下会变为多态内联缓存;后两级缓存则存着一些之前用过的表达式树,便于拼接出新的逻辑来生成新的IL构成新的委托去更新最初的一级缓存——靠SRE动态生成的轻量方法的委托。

    CLR能直接跑的是IL(的二进制形式),不是C#(的文本形式)。如果说用CodeDOM在运行时编译C#代码,那也是借CodeDOM里的C# service provider之手来生成IL。当需要做的动态的事情比“调用一个现成的方法”要复杂时,要高效的实现就还是得靠IL了……嗯除非你想绕开CLR的限制自己生成机器码 =_=

  49. 老赵
    admin
    链接

    老赵 2009-12-25 23:06:00

    @RednaxelaFX
    希望Expression Tree可以更好用,这样IL就少了,呵呵。
    话说有什么办法可以绕开CLR限制生成机器码的办法吗?

  50. RednaxelaFX
    *.*.*.*
    链接

    RednaxelaFX 2009-12-25 23:22:00

    @Jeffrey Zhao
    办法很多。通用的办法是P/Invoke,自己在native code提供能得到可执行内存空间的东西;这要怎么提供就可以很多花样了。另外还可以利用CLR特定的实现方式……但这只适合娱乐 =_=|||
    总之在低权限/非full-trust的条件下这些是玩不了的

    Mono里我还试过运行时改变对象的实际类型(不是改变变量的引用类型哦)。蛋太疼了orz
    效果像这样:

    var foo = new Foo();
    // 经过一段神奇的代码
    var array = (uint[])(object)foo;
    array[2] = 3;

  51. 装配脑袋
    *.*.*.*
    链接

    装配脑袋 2009-12-28 11:36:00

    如今CPU都有NX bits功能,加上OS的DEP,想干那种坏事不太容易了……

  52. YJJ
    *.*.*.*
    链接

    YJJ 2010-01-08 15:33:00

    有道理
    但是对 IL书籍 作者的打击比较沉重.........

  53. cuishengli
    61.184.205.*
    链接

    cuishengli 2010-09-03 21:26:28

    C#的构造函数名称使用类名称不好,不如就用ctor。

  54. 寒江雪
    116.231.91.*
    链接

    寒江雪 2011-08-10 14:00:09

    我一直在纠结要不要学IL,看了你的文章终于有了决定

  55. old
    112.25.208.*
    链接

    old 2014-11-26 16:16:22

    "于是,在用到Emit的时候,您就可以先写一些C#目标代码并编译成程序集,然后用.NET Reflector将其反编译成IL,一条一条指令地“抄”至程序中" 这个好,不用再去啃IL了。

发表回复

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

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

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

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

使用Live Messenger联系我