Introduzione al CLR/MSIL

Slides:



Advertisements
Presentazioni simili
Ambiente Java.
Advertisements

Carlo Becchi .NET Tutorial Carlo Becchi
INTRODUZIONE Il framework.NET. Un po di storia Sin dalla prima versione del sistema operativo Windows (1990 circa), nacque la necessità di far comunicare.
Code::Blocks Ambiente di sviluppo.
Costruttori e Distruttori
Recupero debito quarto anno Primo incontro
Corrado Cavalli Microsoft .NET MVP
ASP .NET & Web Service: Introduzione
Consumare Web Service Andrea Saltarello
26/10/2004Laboratorio di Programmazione - Luca Tesei1 Variabili e Oggetti Lo spazio di memoria di Java Le API di Java.
L’architettura della Java Virtual Machine
Massa Laura Mela Enrica
1 Semantica Operazionale di un frammento di Java: lo stato.
Classi ed Oggetti in Java (Cenni). Richiami Ruolo delle Classi in Java Oggetti.
Semantica Operazionale di un frammento di Java: lo stato
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Le componenti di un calcolatore CPU CPU Intel x86, AMD Intel x86, AMD Memoria volatile Memoria volatile RAM RAM Memorie di massa Memorie di massa Hard.
Programmazione Procedurale in Linguaggio C++
Distributed Object Computing
1 Programmazione ad oggetti in Java E.Mumolo, DEEI
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Introduzione a JAVA Anno Accademico 2009/2010.
Introduzione al linguaggio Java
Programmazione Un programma descrive al computer, in estremo dettaglio, la sequenza di passi necessari a svolgere un particolare compito L’attività di.
Perché.Net e non più COM/DCOM ? Superamento dei problemi di COM: Richiede una infrastruttura "non semplice" da ogni applicazione (ad esempio Class Factory.
Gestione dei Progetti Software 2 (a.a. 2004/05) - Lezione 3 1 JAVA e Internet: il World Wide Web Internet: milioni di computer collegati fra di loro attraverso.
Approfondimento delle classi
CAPITOLO 1 JAVA: UN TUFFO NEL LINGUAGGIO E NELL'AMBIENTE.
CAPITOLO 4 LINGUAGGIO JAVA: COSTRUTTI DI BASE. ALFABETO Java adotta la codifica standard Unicode della società Unicode, Inc. (ftp://ftp.unicode.org) definito.
CAPITOLO 2 INTRODUZIONE AL LINGUAGGIO JAVA E ALL'AMBIENTE HOTJAVA.
memoria gestita staticamente:
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
Introduzione ad ASP.net
Argomenti della lezione
C# LE BASI 2007 Prima lezione - Introduzione.
Elementi di programmazione ad oggetti a. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria.
Introduzione a C#.
Ereditarietà e Polimorfismo
Java Contardi Carlo A.S. 2008/09.
1 Introduzione. 2 Le motivazioni In.net Framework iniziato nel 2000 rappresenta una svolta nella tecnologia Microsoft per andare oltre ai linguaggi esistenti.
Namespaces 1. Utilizzati per contenere tipi (classi, strutture, interfacce … ) ed altri namespaces La Class Library è organizzata gerarchicamente mediante.
Implementazione di un linguaggio ad alto livello (con riferimento a Java)
Enumerazioni e Classi 1. Enumerazioni Permettono di definire nuovi tipi che consistono in un insieme di valori costanti (ognuno con un nome) – Migliorano.
Sintassi base e struttura di un programma
Java come linguaggio di programmazione
1 Lucidi delle esercitazioni di Sistemi di Elaborazione in Rete Università degli Studi della Calabria Corso di Laurea in Ingegneria Gestionale A.A. 2003/2004.
Fondamenti di Programmazione Prof.ssa Elisa Tiezzi
ISTITUTO STATALE DI ISTRUZIONE SUPERIORE F. ENRIQUES CORSO JAVA – PROVA INTERMEDIA DEL 12 MARZO 2007 NOME: COGNOME: ________________________________________________________________________________.
I nomi in Java F. Bombi 18 novembre novembre 2003.
Introduzione al C Davide Gadia.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
JAVA Per iniziare. Verificare installazione javac –version java –version Cercare i files e sistemare eventualmente il path.
CORSO DI PROGRAMMAZIONE II Lezione 22
Programmazione ad oggetti
FUNZIONI Dichiarazione: Definizione:
Introduzione a Javascript
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 7 Tipi di dato e strutture dati Specifica e realizzazione di strutture informative come classi.
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
© Copyright NTT DATA Italia – All Rights Reserved The information contained in this document is the property of NTT DATA Italia S.p.A. and the addressee.
TW Asp - Active Server Pages Nicola Gessa. TW Nicola Gessa Introduzione n Con l’acronimo ASP (Active Server Pages) si identifica NON un linguaggio di.
PiattaformePiattaformePiattaformePiattaforme Antonio Cisternino 11 Marzo 2005 OpenSourceOpenSourceOpenSourceOpenSource e ProprietarieProprietarieProprietarieProprietarie.
1 Macchine astratte, linguaggi, interpretazione, compilazione.
Classi ed Oggetti in Java (Cenni). Richiami Cenni sull’ Implementazione, Macchine Astratte, Compilatore, Interprete Ruolo delle Classi in Java Oggetti.
LIP: 4 Maggio 2007 Interfacce. Cos’e’ una Interfaccia una interfaccia e’ un particolare tipo di classe contiene solo la specifica non ha implementazione.
Introduzione all’Ereditarietà Pietro Palladino. Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Definisce.
Introduzione alle Classi e agli Oggetti in Java 1.
Transcript della presentazione:

Introduzione al CLR/MSIL Alfredo Paolillo e Marco Servetto

Vocabolario IL: MSIL: Intermediate Language, Standard ECMA del 1997 Microsoft IL, Implementazione Microsoft di IL

Introduzione Perché .NET Ambiente di esecuzione Common Language Runtime

Perché .NET Difficile effettuare sviluppo omogeneo Molto tempo viene dedicato a far comunicare i vari “strati” Serve un salto qualitativo per semplificare lo scenario

Codici Evoluzione Codice nativo Codice interpretato Codice MSIL

Codice nativo Sorgenti Compilatore Codice nativo (.EXE) Output

Codice interpretato Sorgenti Interprete Output

Codice MSIL Codice MSIL Compilatore .NET Sorgenti (Assembly) .EXE/.DLL Codice nativo Output Compilatore JIT

Codice MSIL Codice MSIL Compilatore .NET Sorgenti (Assembly) .EXE/.DLL Codice + metadati Codice nativo Output Compilatore JIT

Ambiente di esecuzione Codice MSIL Ambiente di esecuzione .NET Runtime Sorgenti Compilatore .NET Codice MSIL (Assembly) .EXE/.DLL Codice nativo Output Compilatore JIT

Motori JIT Inizialmente previsti 4 motori: Motore Descrizione Dove si trova JIT Attuale implementazione OptiJit Codice più ottimizzato Non implementato FastJit Esecuzione JIT più veloce .NET Compact Framework Native (Pre-Jit) Compilazione preventiva, assembly compilato salvato in GAC NGEN.EXE

JIT – Just in Time Compiler In teoria, come con Java, è possibile compilare MSIL ed eseguirlo (interpretato) in qualsiasi ambiente che supporti l’esecuzione La compilazione di un’applicazione da un tipo di codice assembly quale MSIL verso un codice eseguibile sulla macchina nativa dovrebbe appesantire le prestazioni dell’applicazione È quello che succede?

JIT – Just in Time Compiler Il codice non viene caricato tutto in memoria il compilatore JIT compila solo il codice necessario, quindi memorizza nella cache il codice nativo compilato per riutilizzarlo L’overhead è una lieve differenza che, nella maggior parte dei casi, non verrà rilevata

JIT – Just in Time Compiler Quando viene caricata una classe, il caricatore aggiunge uno stub a ogni metodo della classe La prima volta che viene chiamato il metodo, il codice stub cede il controllo al compilatore JIT, che compila MSIL nel codice nativo. Lo stub viene quindi modificato per puntare al codice nativo appena creato, affinché le chiamate successive passino direttamente al codice nativo

Indipendenza dalla piattaforma .NET è un’implementazione di CLI Common Language Infrastructure CLI è uno standard ECMA ECMA-334, ECMA-335 Esistono già altre implementazioni di CLI: SSCLI (Microsoft, per Windows, FreeBSD e Macintosh) Mono (per Linux) DotGNU Intel OCL (Open CLI Library) …

Codice IL Tutto questo assomiglia a qualcosa di già visto? Forse Java? Ci sono delle differenze Un compilatore Java crea bytecode, che in fase di esecuzione viene interpretato tramite JVM .NET crea un codice nativo

Codice IL Un vantaggio rilevante offerto da .NET Framework rispetto a Java e JVM è la scelta del linguaggio di programmazione JVM solo Java .NET Multilinguaggio (VB.net, C#, J# etc…) Vediamo un esempio di IL

Assembly Assembly Modulo (file PE) Codice IL Metadati Manifest Nota: si riprendono gli assembly più avanti, non approfondire troppo su questa slide e sulla precedente. Assembly

Metadati Concetto chiave in .NET Informazioni sui tipi di un assembly Generati automaticamente dai compilatori Estendibili da terze parti Formato binario rappresentabile con XML: XML Schema (XSD) Serializzazione e deserializzazione oggetti a runtime in XML

Metadati Descrizione di un assembly Descrizione dei tipi Identità: nome, versione, cultura [, pubblic key] Tipi esportati Assembly da cui dipende Descrizione dei tipi Nome, visibilità, classe base, interfacce implementate Attributi custom Definiti dall’utente Definiti dal compilatore

Codice IL Proviamo adesso a scrivere e compilare dei semplici programmi in C# e proviamo ad analizzarli Si è scelto C# perché è il linguaggio attualmente più utilizzato in ambiente .NET, ma questo non influenza quello che andremo a vedere

Codice IL Esempio 1 namespace testUno { public class esempioUno public esempioUno() } static void Main(string[] args) int primaVariabile = 0x1234; int secondaVariabile = 0xabcdef; Tralasciando il concetto di namespace, molto simile a quello visto per XML, e la sintassi, andiamo a preoccuparci della semantica. Si è dichiarata una classe esempioUno con costruttore vuoto. Nel main vengono assegnati dei valori int alle variabili

Codice IL Il file eseguibile è costituito da due parti: la prima è il codice MSIL, utilizzato per generare il codice nativo la seconda è rappresentata dai metadati Con un tool in dotazione con l’SDK possiamo Diassemblare il file ottenuto dalla compilazione Otterremo il seguente output Tralasceremo comunque alcuni dettagli come il codice del costruttore di classe Bisogna sottolineare che il codice MSIL è una implementazione di IL, ma non è quello standard. I metadati inoltre sono aggiunti dal compilatore, dal framework e volendo dall’utente stesso. Per quanto rigurada quest’ultimi non si è riusciti a reperire della documentazione da fonti sicure per cui le assunzioni riportate in seguito sono state ottenuto da test.

Codice IL .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 13 (0xd) .maxstack 1 .locals init (int32 V_0, int32 V_1) IL_0000: ldc.i4 0x1234 IL_0005: stloc.0 IL_0006: ldc.i4 0xabcdef IL_000b: stloc.1 IL_000c: ret } // end of method esempioUno::Main Vediamo che è un linguaggio molto simile all’assembler, rimanendo comunque molto più chiaro e semanticamente più complicato

Codice IL – istruzioni principali .entrypoint Specifies that this method is the entry point to the application (only one such method is allowed). .maxstack int32 specifies the maximum number of elements on the evaluation stack during the execution of the method .locals [init] Defines a set of local variables for this method. ldc.i4: Description Push num of type int32 onto the stack as int32. stloc.0: Description: Pop value from stack into local variable 0. ret: Description: return from method, possibly returning a value

Codice IL – Metainformazioni ScopeName : testUno.exe MVID : {F01C8E38-E942-43D9-9D71-95D37789D357} =========================================================== Global functions ------------------------------------------------------- Global fields Global MemberRefs TypeDef #1 TypDefName: testUno.esempioUno (02000002) Flags : [Public] [AutoLayout] [Class] [AnsiClass] (00100001) Extends : 01000001 [TypeRef] System.Object Method #1 MethodName: .ctor (06000001) Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886) RVA : 0x00002050 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. Method #2 [ENTRYPOINT] MethodName: Main (06000002) Flags : [Private] [Static] [HideBySig] [ReuseSlot] (00000091) RVA : 0x00002064 1 Arguments Argument #1: SZArray String 1 Parameters (1) ParamToken : (08000001) Name : args flags: [none] (00000000) Listato dei metadati assolutamente da non tenere in considerazione. Tale listato è stato riportato solo al fine di dare un’idea della quantità di meta-informazioni all’interno di un assembly.

Codice IL – Metainformazioni TypeRef #1 (01000001) ------------------------------------------------------- Token: 0x01000001 ResolutionScope: 0x23000001 TypeRefName: System.Object MemberRef #1 Member: (0a000002) .ctor: CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. TypeRef #2 (01000002) Token: 0x01000002 TypeRefName: System.Diagnostics.DebuggableAttribute Member: (0a000001) .ctor: 2 Arguments Argument #1: Boolean Argument #2: Boolean

Codice IL – Metainformazioni Signature #1 (0x11000001) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 2 Arguments Argument #1: I4 Argument #2: I4 Assembly Token: 0x20000001 Name : testUno Public Key : Hash Algorithm : 0x00008004 Major Version: 0x00000000 Minor Version: 0x00000000 Build Number: 0x00000000 Revision Number: 0x00000000 Locale: <null> Flags : [SideBySideCompatible] (00000000) CustomAttribute #1 (0c000001) CustomAttribute Type: 0a000001 CustomAttributeName: System.Diagnostics.DebuggableAttribute :: instance void .ctor(bool,bool) Length: 6 Value : 01 00 00 01 00 00 > < ctor args: ( <can not decode> ) Chiariremo in seguito la parte in rosso

Codice IL – Metainformazioni AssemblyRef #1 ------------------------------------------------------- Token: 0x23000001 Public Key or Token: b7 7a 5c 56 19 34 e0 89 Name: mscorlib Major Version: 0x00000001 Minor Version: 0x00000000 Build Number: 0x00001388 Revision Number: 0x00000000 Locale: <null> HashValue Blob: Flags: [none] (00000000)

Codice IL I metadati vengono organizzati in tabelle, in cui fondamentalmente viene descritto ciò che il codice definisce e a cui fa riferimento Prestiamo attenzione a questa parte di codice: CallCnvntn: [LOCALSIG] 2 Arguments Argument #1: I4 Argument #2: I4 Parte interessante dei metadati: Vediamo che abbiamo due argomenti, questi non sono altro che i due interi da 4 Byte dichiarati nel Main

Codice C# Proviamo adesso a compilare il seguente codice FILE:esempioDueB namespace testDue { public class esempioDueB static void Main(string[] args) esempioDueA variabile = new esempioDueA(); variabile.printString(); } In questo secondo esempio istanziamo una classe esempioDueA e ne invochiamo il metodo printString() che come vedremo è un metodo che non restituisce nulla e non ha parametri

Codice C# FILE: esempioDueA using System; namespace testDue { public class esempioDueA public esempioDueA() } public void printString() string s = "Hello!!!!"; Console.Write(s); Tralasciamo la direttiva using, che è poi l’equivalente dello usin in java. Vediamo il costruttore vuoto e il metodo printString(). In quest’ultimo notiamo l’assegnazione della stringa e la successiva stampa.

Codice IL Disassembliamo: A differenza di prima dovremo analizzare due codici

Codice IL .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 13 (0xd) .maxstack 1 .locals init (class testDue.esempioDueA V_0) IL_0000: newobj instance void testDue.esempioDueA::.ctor() IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: callvirt instance void testDue.esempioDueA::printString() IL_000c: ret } // end of method esempioDueB::Main Visualizzazione del codice MSIL della classe contenente il main. Da notare l’istruzione .entrypoint Vediamo che come variabili abbiamo solo una classe più alcune istruzioni descritte nelle slide successive

Codice IL .method public hidebysig instance void printString() cil managed { // Code size 13 (0xd) .maxstack 1 .locals init (string V_0) IL_0000: ldstr "Hello!!!!" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: call void [mscorlib]System.Console::Write(string) IL_000c: ret } // end of method esempioDueA::printString

Codice IL Principali differenze rispetto al codice precedente: Newobj: Assembli format: newobjctor Description: allocate an uninitialized object or value type and call ctor Call: Assembli format: call method Description: Call method described by method Callvirt: Assembli format: callvirt method Description: Call a method associated with obj

Codice IL Andiamo nuovamente a riesaminare le meta-informazioni: Signature #2 (0x11000002) (EsempioDueB) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 1 Arguments Argument #1: Class testDue.esempioDueA Signature #1 (0x11000001) (EsempioDueA) Argument #1: String Vediamo che la segnature delle classi è differente Nella prima, quella del main, abbiamo un solo argomento di tipo esempioDueA, questo perché al suo interno creiamo una istanza della classe. Nella seconda l’unico argomento è una stringa, quella che stampiamo.

Codice IL – Metainformazioni Method #2 (definizione del metodo invocato dalla call) ------------------------------------------------------- MethodName: printString (06000002) Flags : [Public] [HideBySig] [ReuseSlot] (00000086) RVA : 0x00002064 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. .................. User Strings (costante) 70000001 : ( 9) L"Hello!!!!” Method #2 definisce il metodo invocato dalla call, vediamo che sono riportati: Nome del metodo Visibilità Se è di tipo managed o no (è unmanaged nel caso in cui, ad esempio, si richiamino parti di codice scritte in C++ che non sono type safe) Tipo di ritorno, in questo caso void Argomenti, in questo caso void Da notare la costante string.

Codice C# Passaggio di parametri: namespace testTre { public class esempioTreA static void Main(string[] args) string s = ("HELLO!!!!!!!!!!!!!!!!!!!!!!!!!!"); esempioTreB variabile = new esempioTreB(); variabile.printString(s); } Questo esempio è molto simile a quello precedente, la differenza è che la stringa da stampare viene passata alla funzione.

Esempio C# Using system; public class esempioTreB { public esempioTreB() } public void printString(string s) Console.Write(s);

Codice IL .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 20 (0x14) .maxstack 2 .locals init (string V_0, class testTre.esempioTreB V_1) IL_0000: ldstr "HELLO!!!!!!!!!!!!!!!!!!!!!!!!!!" IL_0005: stloc.0 IL_0006: newobj instance void testTre.esempioTreB::.ctor() IL_000b: stloc.1 IL_000c: ldloc.1 IL_000d: ldloc.0 IL_000e: callvirt instance void testTre.esempioTreB::printString(string) IL_0013: ret } // end of method esempioTreA::Main Una cosa molto importante da notare è che il printString è chiamato con un string come parametro e non con il puntatore alla variabile da stampare.

Codice IL .method public hidebysig instance void printString(string s) cil managed { // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.1 IL_0001: call void [mscorlib]System.Console::Write(string) IL_0006: ret } // end of method esempioTreB::printString

Codice IL ldarg.1 Assembli format: ldarg.1 Description: Load argument 1 onto stack Esistono anche delle varianti, ad esempio: ldarg num Assembli format: ldarg num Description: Load argument numbered num onto stack.

Codice IL – Metainformazioni TypeDef #1 ------------------------------------------------------- TypDefName: testTre.esempioTreB (02000002) Flags : [Public] [AutoLayout] [Class] [AnsiClass] (00100001) Extends : 01000001 [TypeRef] System.Object Method #1 MethodName: .ctor (06000001) Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] (00001886) RVA : 0x00002050 ImplFlags : [IL] [Managed] (00000000) CallCnvntn: [DEFAULT] hasThis ReturnType: Void No arguments. Method #2 MethodName: printString (06000002) Flags : [Public] [HideBySig] [ReuseSlot] (00000086) RVA : 0x00002064 1 Arguments Argument #1: String 1 Parameters (1) ParamToken : (08000001) Name : s flags: [none] (00000000) Poco codice ci interessa. Esaminato nella slide successiva.

Codice IL – Metainformazioni Signature #1 (0x11000001) ------------------------------------------------------- CallCnvntn: [LOCALSIG] 2 Arguments Argument #1: String Argument #2: Class testTre.esempioTreB Assenza di Signature #2 La classe su cui viene invocato il metodo printString non ha dichiarazioni locali In questo caso abbiamo due argomenti nella classe contenente il main: La stringa da stampare L’istanza della classe su cui viene invocato il metodo La classe contenete il metodo printString non ha una segnatura in quanto non ha variabili al suo interno.

Garbage Collector Gli oggetti vengono distrutti automaticamente quando non sono più referenziati Algoritmo Mark-and-Compact

Garbage Collector - fase 1: Mark NextObjPtr Root set Oggetti “vivi” Oggetti non raggiungibili Spazio libero

Garbage Collector - fase 2: Compact Spazio recuperato NextObjPtr Root set Oggetti “vivi” Spazio libero

GC e distruzione deterministica In alcuni casi serve un comportamento di finalizzazione deterministica: Riferimenti a oggetti non gestiti Utilizzo di risorse che devono essere rilasciate appena termina il loro utilizzo Non si possono usare i finalizzatori, che non sono richiamabili direttamente Implementare l’interfaccia IDisposable

Common Type System Tutto è un oggetto Due categorie di tipi: Tipi reference (riferimento) Allocati su heap gestito Tipi value (valore) Allocati su stack o in oggetti gestiti (reference) Tutti i tipi value possono essere visti come tipi reference Boxing

Tipi value e reference in memoria public struct Size { public int height; public int weight; } public class CSize { void Main() { Size v; // v istanza di Size v.height = 100; // ok CSize r; // r è un reference r.height = 100; // illegale, r non assegnato r = new CSize(); // r fa riferimento a un CSize r.height = 100; // ok, r inizializzata Stack Heap v.height v.width height width r Class CSize

Equivalenza e identità Il confronto tra oggetti può essere: di equivalenza Object.Equals: oggetti con stesso tipo e uguale contenuto di identità Object.ReferenceEquals: stessa istanza o entrambi null ==: dipende dal tipo (come ReferenceEquals o altro) Object.GetHashCode: rappresentazione univoca istanza Stack Heap r1 height width r2=r1; r2 Class CSize

Equivalenza e identità “Teo” 19 a true c false b a ==d .Equals(d) b “Ugo” 38 c d “Ugo” 38

Boxing I tipi value si possono sottoporre a “boxing” per supportare le funzionalità tipiche degli oggetti Un tipo value “boxed” è un clone indipendente Un tipo value “boxed” può tornare ad essere value (unboxing) System.Object è il tipo universale

Boxing Stack Heap Boxing Unboxing i o k int i = 123; object o = i; int k = (int)o; i 123 Heap int i = 123; o int 123 object o = i; k Boxing 123 int j = (int)o; Unboxing

Conclusioni Evoluzione della macchina virtuale Non tutto è documentato Si cerca di trovare il miglior compromesso tra sicurezza, flessibilità e prestazioni Non tutto è documentato Scarsa documentazione per quanto riguarda i metadati

Altre Informazioni Dove posso ottenere maggiori informazioni www.microsoft.com/msdn/italy/studenti www.ugidotnet.org www.gotdotnet.com www.ecma-international.org Developer resources Microsoft Visual Studio.NET Microsoft .NET Framework SDK Microsoft Developer Network