In the last part of the eight-part interview with Anders Hejlsberg, Bill Venners talks with Anders about the different CLR design choices. An example of this is having only one add and sub instruction for all types. In Java bytecode you have separate instructions for adding integers, floats, doubles etc. in MSIL (the intermediate code for .NET) you don't. Anders: "If an interpreter can just blindly do what the instructions say without needing to track what's at the top of the stack, it can go faster. When it sees an iadd, for example, the interpreter doesn't first have to figure out which kind of add it is, it knows it's an integer add. Assuming someone has already verified that the stack looks correct, it's safe to cut some time there, and you care about that for an interpreter. In our case, though, we never intended to target an interpreted scenario with the CLR. We intended to always JIT [Just-in-time compile], and for the purposes of the JIT, we needed to track the type information anyway. Since we already have the type information, it doesn't actually buy us anything to put it in the instructions."
This made me realise this would make the production of a processor which takes MSIL as it's native machine code impossible. Sun developed a chip that could interpret Java bytecode natively a while ago, the picoJava II, with MSIL this would be a lot harder to do.