Une des grosses nouveautés apportée par le framework .Net est l'interopérabilité entre les langages supportés. Cela est possible de part son architecture. En effet, le framwork a été concu pour éxécuter du code que l'on appelle du code intermédiaire, ou Intermediate Language ou encore IL. Ce code est éxécuté par le CLR qui fait appel au fonctions du système. Le développeur utilise la bibliothèque de classes fournie avec le framework pour construire un programme. Ce sont ces classes qui s'occupent d'interagir avec le CLR et le CLR de faire les appels systèmes. LE schéma suivant montre cette architecture.
L'interopérabilité entre les langages intervient donc au niveau de la génération de l'IL par le compilateur et l'édition des liens qui est effectuée sur les fichiers contenant l'IL pour créer l'executable. Donc pour qu'un langage puisse etre compatible .Net, il faut avoir un compilateur qui puisse générer de l'IL. Cela permet l'appel de méthode sur d'autres objets, l'héritage d'implémentations provenant d'autres objets, le transfert d'instances d'une classe vers d'autres objets, l'utilisation d'un débogueur unique pour plusieurs objets, et la récupération d'erreurs provenant d'autres objets.
Le schéma suivant montre comment l'interopérabilité entre les langages est possible :
Une fois compilés de cette manière, les programmes
sont exécutables mais pas encore pleinement fonctionnels. En effet, lors
de sa première exécution, un programme compilé en IL sera
recompilé en code natif, afin de gagner en rapidité.(Cette méthode
de compilation s'appelle la compilation "Just In Time") C'est pour
cela que le premier lancement d'un programme .NET peut s'avérer lent.
Bien sûr, lors des exécutions suivantes, le programme fonctionnera
à pleine vitesse.