Cenni preliminari su Common Language Runtime

I compilatori e gli strumenti dei linguaggi espongono le funzionalità di Common Language Runtime e consentono di scrivere codice che sfrutta i vantaggi di tale ambiente di esecuzione gestita. Il codice sviluppato tramite un compilatore di linguaggio basato su Common Language Runtime viene definito codice gestito e si avvantaggia di funzionalità quali l'integrazione tra i linguaggi, la gestione delle eccezioni con linguaggi diversi, la sicurezza avanzata, il supporto per il controllo delle versioni e la distribuzione, un modello semplificato per l'interazione tra componenti e servizi di debug e di profiling.

Per consentire all'ambiente di esecuzione di fornire servizi al codice gestito, è necessario che i compilatori di linguaggio generino metadati che descrivono i tipi, i membri e i riferimenti presenti nel codice. I metadati sono memorizzati con il codice: ogni file eseguibile trasportabile (PE, Portable Executable) caricabile in Common Language Runtime contiene metadati. I metadati vengono utilizzati nell'ambiente di esecuzione per individuare e caricare classi, disporre istanze in memoria, risolvere chiamate di metodo, generare codice nativo, garantire sicurezza e impostare limiti di contesto per la fase di esecuzione.

Il layout degli oggetti e i riferimenti agli oggetti vengono gestiti automaticamente: quando non sono più in uso, gli oggetti vengono rilasciati. Gli oggetti la cui durata viene amministrata con queste modalità vengono denominati dati gestiti. La procedura di Garbage Collection consente di eliminare il rischio di perdite di memoria e di altri errori comuni di programmazione. Se si impiega codice gestito, è possibile utilizzare nell'applicazione .NET Framework sia dati gestiti che dati non gestiti, anche simultaneamente. Dal momento che i compilatori di linguaggio forniscono autonomamente tipi, quali i tipi primitivi, è possibile che non sempre lo sviluppatore sappia, o abbia l'esigenza di sapere, se i dati che utilizza sono gestiti.

Common Language Runtime facilita la progettazione di componenti e applicazioni i cui oggetti interagiscano in contesti di linguaggi diversi. Oggetti scritti in linguaggi differenti possono infatti interagire e funzionare in modo strettamente integrato. Una volta definita una classe, ad esempio, è possibile utilizzare un linguaggio differente per derivarne un'altra classe o per chiamarvi un metodo. È anche possibile passare l'istanza di una classe al metodo di una classe scritta in un linguaggio differente. Questa integrazione tra linguaggi è possibile perché i compilatori e gli strumenti dei linguaggi destinati alla fase di esecuzione utilizzano un sistema di tipi comuni, definito dall'ambiente di esecuzione, e seguono le regole di tale ambiente per la definizione di nuovi tipi, oltre che per la creazione, l'utilizzo, il mantenimento e l'associazione a tipi.

In quanto parte dei rispettivi metadati, tutti i componenti gestiti contengono informazioni sui componenti e le risorse in base ai quali sono stati generati. Il runtime utilizza tali informazioni per garantire la disponibilità delle versioni specificate del software necessario al funzionamento del componente o dell'applicazione, riducendo così il rischio di interruzioni del codice dovute all'irreperibilità di alcune dipendenze. Le informazioni di registrazione e i dati dello stato non vengono più memorizzati nel Registro di sistema, in cui poteva essere difficile individuarli e gestirli. Le informazioni sui tipi definiti e sulle relative dipendenze vengono invece memorizzate con il codice in forma di metadati, semplificando di gran lunga le attività di replica e rimozione di componenti.

I compilatori e gli strumenti dei linguaggi sono progettati per esporre le funzionalità del runtime secondo modalità utili e intuitive per gli sviluppatori. Alcune di queste funzionalità potrebbero quindi essere più evidenti in un ambiente operativo anziché in un altro. Il modo di percepire il funzionamento dell'ambiente di esecuzione dipende dai compilatori o dagli strumenti dei linguaggi utilizzati. Lo sviluppatore in Visual Basic, ad esempio, potrà rilevare in questo linguaggio una maggiore presenza di funzionalità orientate a oggetti, conferitagli da Common Language Runtime. Di seguito sono riportati alcuni dei vantaggi del runtime:

  • I miglioramenti delle prestazioni.

  • La possibilità di utilizzare con facilità componenti sviluppati in altri linguaggi.

  • La disponibilità dei tipi estensibili forniti da una libreria di classi.

  • Nuove funzionalità di linguaggio: l'ereditarietà, le interfacce e l'overload, di cui può avvantaggiarsi la programmazione orientata ad oggetti; il supporto per il threading Free esplicito, che consente la creazione di applicazioni multithread e scalabili; infine, il supporto per la gestione strutturata delle eccezioni e gli attributi personalizzati.

Se si utilizza Microsoft® Visual C++® .NET, è possibile scrivere codice gestito utilizzando Visual C++, che consente di sfruttare i vantaggi di un ambiente di esecuzione gestita continuando ad accedere alle potenti funzionalità e agli efficaci tipi di dati già noti. Altre funzionalità del runtime sono:

  • L'integrazione tra linguaggi, in particolare l'ereditarietà tra linguaggi.

  • Procedura di Garbage Collection, che consente di gestire la durata degli oggetti rendendo superfluo il conteggio dei riferimenti.

  • Gli oggetti autodescrittivi, che rendono superfluo l'utilizzo del linguaggio di definizione dell'interfaccia (IDL, Interface Definition Language).

  • La possibilità di compilare il codice una sola volta e di eseguirlo su qualsiasi CPU e sistema operativo che supporta Common Language Runtime.

È anche possibile scrivere codice gestito utilizzando il linguaggio C#, con i seguenti vantaggi:

  • Progettazione completamente orientata ad oggetti.

  • Completa indipendenza dai tipi.

  • Efficace combinazione tra la semplicità di Visual Basic e la potenza di C++.

  • Garbage Collection.

  • Sintassi e parole chiave analoghe a quelle utilizzate in C e C++.

  • Utilizzo dei delegati invece dei puntatori a funzioni con conseguente miglioramento dell'indipendenza e della sicurezza dei tipi. I puntatori a funzione sono disponibili mediante l'utilizzo della parola chiave di C# unsafe e dell'opzione del compilatore C# (Csc.exe) /unsafe per il codice e i dati non gestiti.

Vedere anche

Concetti

Processo di esecuzione gestita

Altre risorse

Cenni preliminari su .NET Framework