你可以在MSIL中做什么,你不能在C#或VB.NET中做什么?
所有使用.NET语言编写的代码都会编译为MSIL,但是您可以直接使用MSIL执行哪些特定的任务/操作?
让我们也让事情在MSIL中比C#,VB.NET,F#,j#或任何其他.NET语言更容易完成。
到目前为止我们有这样的:
raise
元素定义事件。 .entrypoint
作为非main()
方法。 int
和本地unsigned int
类型。 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,你可以得到一个只能在程序集内派生类访问的成员。 (我认为这可能非常有用!)
上一篇: What can you do in MSIL that you cannot do in C# or VB.NET?