Donc à peu près toutes les réponses ici traitent de la portabilité future du code, ce qui n'est pas vraiment concerné. La raison pour laquelle il fonctionnait dans une VM est en grande partie qu'il y a des avantages à fonctionner dans une VM !
Au début de .NET, il y avait C#/VB.NET/C++(cli)/etc. Écrire du code pour être capable d'interagir entre eux ne serait pas si difficile que cela, contrairement à la production de l'ensemble du CLR et des spécifications variables qui allaient avec. Pourquoi formaliser l'IL si notre seul objectif est de permettre les appels inter-langues etc...
L'intérêt de les faire tous compiler dans le même langage intermédiaire (ok le mode mixte C++ est une aberration) était un peu différent. Il y a une raison vraiment évidente pour laquelle les choses ont pris cette direction. Si vous regardez en arrière historiquement, à l'approche de l'an 2000, il y avait de sérieuses questions quant à savoir si x86 allait être "l'architecture" dans le futur (pas mal de normes concurrentes arrivaient/partaient ; les fenêtres supportaient même plusieurs !) et un gros point de douleur était d'obtenir que le code fonctionne sur plusieurs environnements (évidemment, le jvm avait aussi cet objectif). Il y avait cependant d'autres problèmes. Un très gros flagrant était la mémoire regardons les tailles de mémoire approximatives sur les machines....
'82 à '84 - 1KB à 16KB
'85 à '89 - 512KB à 640KB
'89 à '92 - 1MB à 2MB
'93 à '94 - 4MB à 8MB
'95 à '99 - 32MB à 128MB
'00 à &apos ;01 - 256MB à 512MB
'02 à '04 - 1GB à 2GB
'05 à '09 - 3GB à 4GB
'10 à aujourd'hui - 6GB à 48GB
Si vous étiez assis au milieu->la fin des années 90, quelle serait l'une de vos principales pensées ?! 32 bit vs 64 bit, ça a l'air d'être un gros problème n'est-ce pas 😉 Notez que de 256mb->2gb était +-4 ans ! Il est probable qu'en tant que société telle que microsoft, vous auriez de gros problèmes de service client de "hi j'ai téléchargé ce logiciel et il ne peut pas fonctionner sur ma machine".
Il y avait de multiples solutions dans l'espace 32/64. Certaines étaient de nouvelles architectures de processeurs certaines comme celle d'intel (enfin une des intels !) étaient des instructions ajoutées. Même si un meilleur matériel avait existé (et que Microsoft avait largué les autres processeurs qu'il supportait), il restait le problème de l'utilisation généralisée de deux systèmes différents. Maintenant, pour un système d'exploitation, ce n'est pas un problème majeur. Mais qu'en est-il de votre application qui prend une photo et y met un chapeau de sorcière ? Vous auriez besoin de compiler pour au moins deux cibles (avec d'autres architectures IA64 (ISA), etc. entrant en jeu, combien de compilations avez-vous besoin ?!) Imaginez maintenant que chaque équipe écrivant une application en interne/un produit/etc doive faire cela. Vous auriez également besoin de tester votre produit sur les différentes architectures, etc, non ? Vous commencez à comprendre le problème ? Le plus grand problème ici, à part les multiples... est l'incertitude. Quelle sera la norme dans 5 ans ? Que se passe-t-il lorsqu'un nouveau processeur sort ?
En guise de remarque, saviez-vous que Windows fonctionnait aussi sur les puces DEC alpha ? DEC Alpha - Wikipedia commençant à voir certains des soucis?
En compilant vers un langage intermédiaire, beaucoup de ces problèmes disparaissent. Je libère du code en langage intermédiaire et il est compilé sur la machine sur laquelle il va être exécuté au fur et à mesure (ou avant ... plus sur ce point plus tard) de son exécution, assez chouette hein ! Cela permet également des optimisations par machine au fur et à mesure que le runtime les fait !!! C'est aussi relativement bon marché à faire (il est beaucoup moins cher de compiler que de coder dans un langage lisible par l'homme). Jetons quelques avantages supplémentaires comme des informations de débogage bien meilleures disponibles au moment de l'exécution également (vous avez déjà vu une exception ? que vous préféreriez que ou "violation d'accès a tenté de lire 0xFFE10FF33") et soudainement cela commence à sembler tout à fait raisonnable.
Avec le runtime il y a un autre avantage et cela a à voir avec l'utilisation de la mémoire / fuites. Il a fourni un tas qui a supporté la collecte des ordures. Oui il y a encore des problèmes et vous pouvez le contourner ! !! mais les problèmes sont relativement rares par rapport à d'autres environnements comme le C++.
Un bit intéressant est qu'à l'origine le CLR avait un objectif secondaire de ne pas fonctionner dynamiquement avec le runtime. Jetez un coup d'œil à ngen Ngen.exe (Native Image Generator). Ngen permet de générer des images natives sur votre machine en compilant à l'avance sur votre machine. Vous pouvez aussi évidemment faire un peu plus d'optimisations etc et votre image peut toujours être exécutée sur plusieurs architectures.
Enfin, les langages sur le CLR pourraient se retrouver quelque part entre C et VB. Vous pourriez en fait être assez flexible et "utiliser des trucs gérés quand cela avait du sens" puis tomber dans quelque chose de plus bas niveau pour le code sensible aux performances (tout en obtenant la plupart des avantages de la plateforme croisée etc pour le code de plus haut niveau).
Je veux souligner qu'il n'y a pas une simple "c'est la réponse". La situation est plus complexe. Il y avait de nombreuses facettes à la décision... Ce n'est pas une seule chose qui a fait que ça s'est produit.