你可以在MSIL中做什么,你不能在C#或VB.NET中做什么?

所有使用.NET语言编写的代码都会编译为MSIL,但是您可以直接使用MSIL执行哪些特定的任务/操作?

让我们也让事情在MSIL中比C#,VB.NET,F#,j#或任何其他.NET语言更容易完成。

到目前为止我们有这样的:

  • 尾递归
  • 通用Co /反变量
  • 重载仅在返回类型中有所不同
  • 覆盖访问修饰符
  • 有一个不能从System.Object继承的类
  • 过滤的异常(可以在vb.net中完成)
  • 调用当前静态类类型的虚拟方法。
  • 获取值类型的盒装版本的句柄。
  • 尝试/错误。
  • 禁用名称的使用。
  • 为值类型定义自己的无参数构造函数。
  • raise元素定义事件。
  • CLR允许一些转换,但不允许C#。
  • .entrypoint作为非main()方法。
  • 直接使用本地int和本地unsigned int类型。
  • 玩瞬态指针
  • MethodBodyItem中的emitbyte指令
  • 抛出并捕获非System.Exception类型
  • 继承枚举(未验证)
  • 您可以将一个字节数组视为一个(4x小)的整数数组。
  • 你可以有一个字段/方法/属性/事件都具有相同的名称(未验证)。
  • 你可以从它自己的catch块分支回try块。
  • 您可以访问famandassem访问说明符( protected internal是fam 汇编)
  • 直接访问用于定义全局函数的<Module>类或模块初始值设定项。

  • MSIL允许重载仅因返回类型而不同

    call void [mscorlib]System.Console::Write(string)
    

    要么

    callvirt int32 ...
    

    包括C#和VB在内的大多数.NET语言都不使用MSIL代码的尾递归功能。

    尾递归是在函数式语言中常见的优化。 它发生在方法A通过返回方法B的值结束时,使方法A的堆栈可以在方法B调用完成后被释放。

    MSIL代码明确支持尾递归,对于某些算法,这可能是一个重要的优化。 但由于C#和VB不生成指令来执行此操作,因此必须手动完成(或使用F#或其他语言)。

    下面是一个如何在C#中手动实现尾递归的例子:

    private static int RecursiveMethod(int myParameter)
    {
        // Body of recursive method
        if (BaseCase(details))
            return result;
        // ...
    
        return RecursiveMethod(modifiedParameter);
    }
    
    // Is transformed into:
    
    private static int RecursiveMethod(int myParameter)
    {
        while (true)
        {
            // Body of recursive method
            if (BaseCase(details))
                return result;
            // ...
    
            myParameter = modifiedParameter;
        }
    }
    

    通过将本地数据从硬件堆栈移动到堆栈分配的堆栈数据结构来移除递归是很常见的做法。 在如上所示的尾调用递归消除中,堆栈被完全消除,这是一个相当不错的优化。 而且,返回值并不需要漫长的调用链,而是直接返回。

    但是,无论如何,CIL提供此功能作为语言的一部分,但使用C#或VB时,必须手动实施。 (抖动也可以自由地进行优化,但这是另一个问题。)


    可以将protected internal访问修饰符组合在一起。 在C#中,如果您编写protected internal成员,则可以从程序集和派生类访问成员。 通过MSIL,你可以得到一个只能在程序集内派生类访问的成员。 (我认为这可能非常有用!)

    链接地址: http://www.djcxy.com/p/14153.html

    上一篇: What can you do in MSIL that you cannot do in C# or VB.NET?

    下一篇: How do I use reflection to call a generic method?