Mael Chiabrera, Software Developer; Viola Bongini, Digital Experience Designe...
Deep diving C# 4 (Raffaele Rialdi)
1. Deep diving C# 4.0 Raffaele Rialdi Twitter: @raffaeler Email:malta@vevy.com Articoli e codice: http://www.iamraf.net Blog:http://blogs.ugidotnet.org/raffaele Profilo MVP:https://mvp.support.microsoft.com/profile/raffaele
2. Quando e come si decide di evolvere un linguaggio Quando si osserva l'adozione su larga scala di un pattern Pattern iterator => C# 2.0 introduce "yield" Filtri su tipi enumerabili => C# 3.0 introduce Linq Metodi helper statici => C# 3.0 introduce gli extension method L'introduzione di uno statement semplifica uno scenario Le novità sono sempre "opt-in" cioè non è obbligatorio usarle
3. Problemi ricorrenti di oggi in C# Uso spinto di reflection Performance povere anche perché non esiste un meccanismo di Cache built-in Ricerca di una soluzione di scripting nelle applicazioni Forse ricordate "VBA for Application"... Quantità industriale di cast durante l'uso di oggetti COM Lo spostamento verso la programmazione dichiarativa
4.
5. Optional e named parameters Negli object model COM viene spesso indicato il valore di default di un parametro Altrettanto spesso ci sono metodi con un numero molto elevato di parametri Optional e named parameters mettono la parola fine Non era mai stata inserita prima perché complica notevolmente la risoluzione degli overload Oggi il driver di queste novità è l'interop e quindi il "costo" è giustificato
6. "ref" optional per i metodi COM Il modificatore ref può essere omesso su metodi e proprietà dei tipi COM solo sui tipi COM: per il compilatore sono un caso speciale Sarebbe stato impossibile chiedere a tutti i produttori di oggetti COM di ricreare le loro PIA il compilatore permette il "trucco" se sulla dichiarazione del Type esiste l'attributo [ComImport] MyCOMObject app = new MyCOMObject(); object m = string.Empty; app.MyMethod(ref m, ref m, ref m, ref m); MyCOMObject app = new MyCOMObject(); app.MyMethod(m, m, m, m);
7. Demo: Office Named parameters Optional parameters Omissione modificatore ref
10. In una operazione di conversione o regola di compilazione ...La Covarianza permette ad un metodo di avere un tipo di ritorno più basso nella gerarchia di derivazione rispetto a quello definito La Controvarianza permette ad un metodo di avere parametri che siano in una gerarchia più alta rispetto a quello definito Classe con gerarchia più bassa Classe con gerarchia più alta
13. DLR Il CLR ha fornito fin'ora un type system di tipo statico e indipendente dai linguaggi Il supporto ai tipi dinamici via Reflection è povero e poco performante. Il DLR è una sorta di "API" sopra il CLR che permette di spostare il controllo sui tipi (binding) al runtime Il DLR è un normale assembly che usa il CLR in modo da supportare i tipi dinamici, tipici dei linguaggi dinamici Iron Python, Iron Ruby, etc. Il CLR classico non è stato modificato per supportare DLR Con il DLR oggi abbiamo queste novità: Expression Trees v2 Dynamic Dispatch Call Site Caching
15. DLR: perché e perché oggi? Non è solo un revival del "late binding"! Il motivo per l'introduzione di questa API è l'interoperabilità semplifica l'interazione con componenti COM Office ma non solo I cast che sono necessari oggi non rendono più sicuro il codice perché c'è sempre la possibilità in un InvalidCastException a runtime. Quindi dynamic non impoverisce la stabilità in questi scenari. semplifica il mix con altri linguaggi Python, Ruby, Javascript semplifica l'uso di DOM che fanno uso di late binding Html e XML privi di schema Esempio: Silverlight V4
16. I Binders Object Binder Per default si comporta in modo analogo del binder statico Javascript Binder (HTML Dom) Python Binder Ruby Binder COM Binder (pensato per Office) Custom Binder
17. Come avviene una call Una CallSite per ogni operazione dinamica La CallSite è l'entità che caratterizza la chiamata parametri, nome, tutto il contesto La CallSite viene inizializzata in modo Lazy La prima volta viene calcolata Le volte successive viene presa da una cache Impatto in perf solo sul primo run È come bruciare una e2prom e poi usarla Possiamo definire la CallSite come un gateway tra CLR e DLR
18. Oggetti dinamicamente tipizzati Calculator calc = GetCalculator(); int sum = calc.Add(10, 20); object calc = GetCalculator(); TypecalcType = calc.GetType(); object res = calcType.InvokeMember("Add", BindingFlags.InvokeMethod, null, newobject[] { 10, 20 }); int sum = Convert.ToInt32(res); ScriptObject calc = GetCalculator(); object res = calc.Invoke("Add", 10, 20); int sum = Convert.ToInt32(res); Tipizzazione statica di un dynamic dynamic calc = GetCalculator(); int sum = calc.Add(10, 20); Invocazione dinamica del metodo Conversionedinamica
19. Scenari d'uso per il DLRReflection Il binder CLR usato dal DLR usa reflection in modo "intelligente" Reflection.Emit viene usato per generare IL a partire dalle Expression v2 Tutto quello che viene fatto dopo è identico (jitting, etc.) Reflection 'classica' è molto più lenta no cache il clr sa già quali overload esistono e come fare il dispatch in più si possono aggiungere altri binder che risolvono per python, ruby, com, etc. etc.
20. Scenari d'uso per il DLR Manipolazione di object che vengono da "qualche parte" Plugin/Addins Usando oggetti COM Usando object model privi di schema (DOM XML, HTML) Quando è possibile, prediligere lo static binding Strong typing significa robustezza del codice Performance
22. PIAPrimary Interop Assembly Le PIA sono gli assembly wrapper primari che permettono di accedere in modo 'semplice' agli oggetti COM Creati a partire dalla type library Necessitano di strong name e di essere registrate in GAC Deploy complesso Se l'object model è grosso (Office) le PIA hanno dimensioni enormi rapportate all'applicazione che le usa Il versioning è un problema Se sviluppo con le PIA di Office 2007, non funziona sulla 2003
23. "no PIA" per COM "no PIA" è una feature che permette di eseguire l'embedding in un assembly del codice di una PIA Depoly di PIA di Office 2007 = 6.5MB Deploy di PIA di Office 2010 = 6.5MB+ Questa versione non funzionerà con Office 2003 Per risolvere questo problema nel CLR 4.0 è stato introdotto il "Type Embedding" (o "No PIA") e la "Type Equivalence" i compilatori hanno un nuovo switch /link per fare l'embedding del solo codice usato di una PIA Si basa su un nuovo attributo, [TypeIdentifier] che grazie al [Guid] già usato in COM, permette di dire al CLR che due tipi sono "Equivalenti"
24. Type Embedding (No PIA) Vengono creati nuovi tipi, copie parziali dei tipi completi presenti nella PIA Invece di una reference alla PIA, avremo un namespace con il codice della PIA all'interno del nostro assembly Nei metadati le VTable hanno degli speciali marker ("_VtblGap1_10") che informano il CLR quanti elementi della VTable sono da saltare il numero 1 è l'indice, il numero 10 è il numero di elementi da saltare
25. Come avviene l'Embedding L'embedding riguarda solo i metadati No codice IL, classi o metodi statici Solo interfacce con attributi ComImport e Guid, delegate, struct semplici, enum Solo i tipi in assembly marcati con: [assembly:Guid(...)] e [assembly:ImportedFromTypeLib(...)]
26. Type Equivalence La Type Equivalence è una diretta conseguenza della possibilità di eseguire l'embedding Assembly A interface ITask { // ... } embedding embedding interface ITask { // ... } interface ITask { // ... } Assembly X Assembly Y type equivalenti
27. E se ...(Type Embedding & Equivalence) Ignoriamo COM Facciamo finta di referenziare una type library che non c'è Eseguiamo l'embedding dell'assembly più scomodo che ci sia: il classico "Common.dll" Contiene tipicamente le interfacce condivise in una architettura Scopriamo nella demo cosa succede
28. Evoluzione di C# DLR2 Script hosting Compiler as a Service Async ??? .NET 4.0 DLR Expression trees v2 Call site caching Dynamic dispatch .NET 3.5 LINQ Language features Expression trees Silverlight .NET 2.0 Generics Fast delegates Dynamic methods .NET 1.0 GC Reflection JIT BCL Code generation Verifier sandbox
29. Cosa arriverà ... Async "Syntactic Sugar" per esecuzione asincrona Compiler as a service Eval di codice a runtime Expression v2 usabili da codice Evoluzione delle expression di Linq MultiStatement E magari che possano essere ricavate senza costruire il tree a mano VB e C# allineati