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:

  • Tail recursion
  • Generic Co/Contravariance
  • Overloads which differ only in return types
  • Override access modifiers
  • Have a class which cannot inherit from System.Object
  • Filtered exceptions (can be done in vb.net)
  • Calling a virtual method of the current static class type.
  • Get a handle on the boxed version of a value type.
  • Do a try/fault.
  • Usage of forbidden names.
  • Define your own parameterless constructors for value types.
  • Define events with a raise element.
  • Some conversions allowed by the CLR but not by C#.
  • Make a non main() method as the .entrypoint .
  • work with the native int and native unsigned int types directly.
  • Play with transient pointers
  • emitbyte directive in MethodBodyItem
  • Throw and catch non System.Exception types
  • Inherit Enums (Unverified)
  • You can treat an array of bytes as a (4x smaller) array of ints.
  • You can have a field/method/property/event all have the same name(Unverified).
  • You can branch back into a try block from its own catch block.
  • You have access to the famandassem access specifier ( protected internal is fam or assem)
  • Direct access to the <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!)

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

    上一篇: F#内联如何工作?

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