What can you do in MSIL that you cannot do in C# or VB.NET?
All code written in .NET languages compiles to MSIL, but are there specific tasks / operations that you can do only using MSIL directly?
Let us also have things done easier in MSIL than C#, VB.NET, F#, j# or any other .NET language.
So far we have this:
raise
element. main()
method as the .entrypoint
. int
and native unsigned int
types directly. protected internal
is fam or assem) <Module>
class for defining global functions, or a module initializer. MSIL allows for overloads which differ only in return types because of
call void [mscorlib]System.Console::Write(string)
or
callvirt int32 ...
Most .Net languages including C# and VB do not use the tail recursion feature of MSIL code.
Tail recursion is an optimization that is common in functional languages. It occurs when a method A ends by returning the value of method B such that method A's stack can be deallocated once the call to method B is made.
MSIL code supports tail recursion explicitly, and for some algorithms this could be a important optimization to make. But since C# and VB do not generate the instructions to do this, it must be done manually (or using F# or some other language).
Here is an example of how tail-recursion may be implemented manually in 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;
}
}
It is common practice to remove recursion by moving the local data from the hardware stack onto a heap-allocated stack data structure. In the tail-call recursion elimination as shown above, the stack is eliminated completely, which is a pretty good optimization. Also, the return value does not have to walk up a long call-chain, but it is returned directly.
But, anyway, the CIL provides this feature as part of the language, but with C# or VB it has to be implemented manually. (The jitter is also free to make this optimization on its own, but that is a whole other issue.)
It's possible to combine the protected
and internal
access modifiers. In C#, if you write protected internal
a member is accessible from the assembly and from derived classes. Via MSIL you can get a member which is accessible from derived classes within the assembly only. (I think that could be pretty useful!)
上一篇: F#内联如何工作?