.NET Framework e tutti i suoi strumenti formano un sistema in due parti: ha un compilatore che compila un linguaggio come C # in un assembly con codice CIL e un compilatore just-in-time (JIT) che compila il CIL per codice macchina.
Un grande vantaggio del CLR è che puoi specificare qualsiasi tipo tu voglia semplicemente usando il suo nome completo. Inoltre, l'assembly specifica in quali assembly è possibile trovare tali tipi. Quindi, quando arriva il compilatore JIT, guarderà il nome di tipo completo, caricherà l'assembly di riferimento che contiene il tipo e lo userà. Il tipo non deve essere conosciuto in anticipo, e non c'è mai un problema con riferimenti circolari. Quindi, se metti alcuni tipi in una libreria principale, tutto ciò che devi fare è assicurarti che gli assembly CLR generati dalla tua lingua facciano riferimento alla tua libreria principale, e quindi i tipi in essi contenuti sono immediatamente disponibili per l'uso.
Il compilatore JIT include solo la logica per gestire alcuni tipi primitivi (numero intero a 32 bit, numero intero a 64 bit, float, riferimenti gestiti e puntatori gestiti) e conosce alcune classi di oggetti molto speciali ( Object
, Enum
, ValueType
, Delegate
, ...). Quasi tutte le altre funzionalità sono simulate con i tipi primitivi (es. Booleano true
è qualsiasi intero con un valore diverso da zero) o supportate tramite chiamate di metodi (virtuali o non virtuali) (proprietà, metodi, operatori sovraccaricati, coercizioni e conversioni tutti usano le chiamate di metodo internamente). Solo alcune funzionalità di base che non possono essere espresse (in modo efficiente) in un linguaggio gestito (come l'aggiunta di numeri interi o l'assegnazione di matrici) sono integrate nel compilatore JIT.