With Visual Studio 2017, we have a new C # language update. After a brief review of Update 6.0, we'll see what's new. The themes of Update 7 are: Working with Data, Improved Perfomances, and Code Simplification.
C# is entering its third decade of life. And it is consistently evolving over the years with lot of new features. Let's recap the recent 7.x evolution and what we expect for the 8.0 features.
C# is entering its third decade of life. And it is consistently evolving over the years with lot of new features. Let's recap the recent 7.x evolution and what we expect for the 8.0 features.
A simple introduction to the Python programming language. In Italian. OLD: superseeded by Pycrashcourse 3.1.
Originally presented during the Networking class of the Computer Science course at the University of Parma
Elementi di C# 1.0
Delegati ed eventi. Eccezioni. Enumeratori.
Elementi di C# 2.0
Static Classes. Generics e collezioni generiche.Nullable Types. Partial Types e Partial Classes. Anonymous Methods.Iteratori,
Elementi di C# 3.0
Auto-implemented properties.Object Initializers e Collection Initializers. Implicit Typed Variables. Anonymous Types.Extension Methods. Lambda Expression.
A simple introduction to the Python programming language. In Italian. OLD: superseeded by Pycrashcourse 3.1.
Originally presented during the Networking class of the Computer Science course at the University of Parma
Elementi di C# 1.0
Delegati ed eventi. Eccezioni. Enumeratori.
Elementi di C# 2.0
Static Classes. Generics e collezioni generiche.Nullable Types. Partial Types e Partial Classes. Anonymous Methods.Iteratori,
Elementi di C# 3.0
Auto-implemented properties.Object Initializers e Collection Initializers. Implicit Typed Variables. Anonymous Types.Extension Methods. Lambda Expression.
Slide introduttive al linguaggio Java 8 in preparazione alla certificazione OCA 1Z0-808.
Lezione del 12-10-2017 tenuta da Valerio Radice presso Nextre Engeneering
https://www.nextre.it/corso/corso-java-oca/
TypeScript ha cambiato il modo di scrivere JavaScript ed in questo talk andiamo a scoprirne le principali caratteristiche per scrivere "JavaScript che non si rompe!"
N.B. Le slides sono aggiornate sino a TS 3.
Programmazione e gestione della sicurezza: Verbale elettronicoDavide Ciambelli
Realizzare un applicativo che permetta di verbalizzare gli esami in forma digitale. Ogni esame sarà formato dal nome dell'insegnamento, la data dell'esame, il nome e il numero di matricola dello studente che sostiene l'esame, il numero di crediti, alcune possibili note o domande effettuate durante l'esame e naturalmente dal voto in trentesimi. L'esame così costituito dovrà essere firmato digitalmente dallo studente. Ogni esame sarà memorizzato in un verbale che conterrà il nome della facoltà, il nome del corso di laurea, il nome dell'insegnamento, la lista dei docenti in commissione. Il verbale per essere “chiuso” dovrà essere corredato da un timestamping e firmato digitalmente da ogni componente della commissione.
What's Big Data? - Big Data Tech - 2015 - FirenzeAlberto Paro
Big Data Tech - 2015 - Florence
Technologie Big Data spiegate al Management
Comprendere i concetti del bigdata e gli strumenti che esistono per affrontarli (Nosql, Hadoop/Spark) sono essenziali al management attuale per poter affrontare le sfide di domani.
Il Corso Programmazione Java Base di K-Tech (http://www.k-tech.it) ha come obiettivo quello di far comprendere le tecniche di programmazione orientata agli oggetti, cioè di modellare e “pensare” a oggetti, di trasmettere i concetti base del linguaggio e le basi per sviluppare piccole applicazioni in modo autonomo.
Il corso Programmazione Java Base è composto da dodici moduli:
1. Introduzione
2. Ciclo di sviluppo
3. Sintassi Elementare
4. Principi OOP
5. Classi e Oggetti
6. Concetti Object Oriented
7. Collections
8. Eccezioni
9. Input Output
10. Serialization
11. Unit Testing
12. Threads
Leggi il programma completo: http://www.k-tech.it/formazione/catalogo/programmazione_java_base
Normalmente parliamo e presentiamo Azure IoT (Central) con un taglio un po' da "maker". In questa sessione, invece, vediamo di parlare allo SCADA engineer. Come si configura Azure IoT Central per il mondo industriale? Dov'è OPC/UA? Cosa c'entra IoT Plug & Play in tutto questo? E Azure IoT Central...quali vantaggi ci da? Cerchiamo di rispondere a queste e ad altre domande in questa sessione...
Allo sviluppatore Azure piacciono i servizi PaaS perchè sono "pronti all'uso". Ma quando proponiamo le nostre soluzioni alle aziende, ci scontriamo con l'IT che apprezza gli elementi infrastrutturali, IaaS. Perchè non (ri)scoprirli aggiungendo anche un pizzico di Hybrid che con il recente Azure Kubernetes Services Edge Essentials si può anche usare in un hardware che si può tenere anche in casa? Quindi scopriremo in questa sessione, tra gli altri, le VNET, le VPN S2S, Azure Arc, i Private Endpoints, e AKS EE.
Static abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptxMarco Parenzan
Did interfaces in C# need evolution? Maybe yes. Are they violating some fundamental principles? We see. Are we asking for some hoops? Let's see all this by telling a story (of code, of course)
Azure Synapse Analytics for your IoT SolutionsMarco Parenzan
Let's find out in this session how Azure Synapse Analytics, with its SQL Serverless Pool, ADX, Data Factory, Notebooks, Spark can be useful for managing data analysis in an IoT solution.
Power BI Streaming Data Flow e Azure IoT Central Marco Parenzan
Dal 2015 gli utilizzatori di Power BI hanno potuto analizzare dati in real-time grazie all'integrazione con altri prodotti e servizi Microsoft. Con streaming dataflow, si porterà l'analisi in tempo reale completamente all'interno di Power BI, rimuovendo la maggior parte delle restrizioni che avevamo, integrando al contempo funzionalità di analisi chiave come la preparazione dei dati in streaming e nessuna creazione di codice. Per vederlo in funzione, studieremo un caso specifico di streaming come l'IoT con Azure IoT Central.
Power BI Streaming Data Flow e Azure IoT CentralMarco Parenzan
Dal 2015 gli utilizzatori di Power BI hanno potuto analizzare dati in real-time grazie all'integrazione con altri prodotti e servizi Microsoft. Con streaming dataflow, si porterà l'analisi in tempo reale completamente all'interno di Power BI, rimuovendo la maggior parte delle restrizioni che avevamo, integrando al contempo funzionalità di analisi chiave come la preparazione dei dati in streaming e nessuna creazione di codice. Per vederlo in funzione, studieremo un caso specifico di streaming come l'IoT con Azure IoT Central.
Power BI Streaming Data Flow e Azure IoT CentralMarco Parenzan
Since 2015, Power BI users have been able to analyze data in real-time thanks to the integration with other Microsoft products and services. With streaming dataflow, you'll bring real-time analytics completely within Power BI, removing most of the restrictions we had, while integrating key analytics features like streaming data preparation and no coding. To see it in action, we will study a specific case of streaming such as IoT with Azure IoT Central.
What are the actors? What are they used for? And how can we develop them? And how are they published and used on Azure? Let's see how it's done in this session
Generic Math, funzionalità ora schedulata per .NET 7, e Azure IoT PnP mi hanno risvegliato un argomento che nel mio passato mi hanno portato a fare due/tre viaggi, grazie all'Università di Trieste, a Cambridge (2006/2007 circa) e a Seattle (2010, quando ho parlato pubblicamente per la prima volta di Azure :) e che mi ha fatto conoscere il mito Don Box!), a parlare di codice in .NET che aveva a che fare con la matematica e con la fisica: le unità di misura e le matrici. L'avvento dei Notebook nel mondo .NET e un vecchio sogno legato alla libreria ANTLR (e tutti i miei esercizi di Code Generation) mi portano a mettere in ordine 'sto minestrone di idee...o almeno ci provo (non so se sta tutto in piedi).
322 / 5,000
Translation results
.NET is better every year for a developer who still dreams of developing a video game. Without pretensions and without talking about Unity or any other framework, just "barebones" .NET code, we will try to write a game (or parts of it) in the 80's style (because I was a kid in those years). In Christmas style.
Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...Marco Parenzan
IoT scenarios necessarily pass through the Edge component and the Raspberry PI is a great way to explore this world. If we need to receive IoT events from sensors, how do I implement an MQTT endpoint? Kafka is a clever way to do this. And how do I process the data? Kafka? Spark? Rabbit ?. How do we write custom code for these environments? .NET, now in version 6 is another clever way to do it! And maybe, we can also communicate with Azure. We'll see in this session if we can make it all work!
How can you handle defects? If you are in a factory, production can produce objects with defects. Or values from sensors can tell you over time that some values are not "normal". What can you do as a developer (not a Data Scientist) with .NET o Azure to detect these anomalies? Let's see how in this session.
Quali vantaggi ci da Azure? Dal punto di vista dello sviluppo software, uno di questi è certamente la varietà dei servizi di gestione dei dati. Questo ci permette di cominciare a non essere SQL centrici ma utilizzare il servizio giusto per il problema giusto fino ad applicare una strategia di Polyglot Persistence (e vedremo cosa significa) nel rispetto di una corretta gestione delle risorse IT e delle pratiche di DevOps.
C'è ancora diffidenza nei confronti dell'Internet of Things e il costo delle soluzioni custom non aiuta. Azure IoT Central è un servizio SaaS personalizzabile che rende accessibile a costi sostenibili. Vediamo quali sonole peculiarità di questo servizio.
Come puoi gestire i difetti? Se sei in una fabbrica, la produzione può produrre oggetti con difetti. Oppure i valori dei sensori possono dirti nel tempo che alcuni valori non sono "normali". Cosa puoi fare come sviluppatore (non come Data Scientist) con .NET o Azure per rilevare queste anomalie? Vediamo come in questa sessione.
It happens that we have to develop several services and deploy them in Azure. They are small, repetitive but different, often not very different. Why not use code generation techniques to simplify the development and implementation of these services? Let's see with .NET comes to meet us and helps us to deploy in Azure.
Running Kafka and Spark on Raspberry PI with Azure and some .net magicMarco Parenzan
IoT scenarios necessarily pass through the Edge component and the Raspberry PI is a great way to explore this world. If we need to receive IoT events from sensors, how do I implement an MQTT endpoint? Kafka is a clever way to do this. And how do I process the data in Kafka? Spark is another clever way of doing this. How do we write custom code for these environments? .NET, now in version 6 is another clever way to do it! And maybe, we also communicate with Azure. We'll see in this session if we can make it all work!
Time Series Anomaly Detection with Azure and .NETTMarco Parenzan
f you have any device or source that generates values over time (also a log from a service), you want to determine if in a time frame, the time serie is correct or you can detect some anomalies. What can you do as a developer (not a Data Scientist) with .NET o Azure? Let's see how in this session.
3. C# LANGUAGE EVOLUTION
C# 1.0 was a new managed language
C# 2.0 introduced generics
C# 3.0 enabled LINQ
C# 4.0 was all about interoperability with dynamic non-strongly typed languages.
C# 5.0 simplified asynchronous programming with the async and await keywords.
C# 6.0 had its compiler completely rewritten from scratch, and introduced a variety
of small features and improvements that were easier to implement now.
8. C#: THE ROAD AHEAD
C# 7.0
It’s there – use it!
C# 7.1
First point release – tiny features
C# 7.2
Safe, efficient low-level code
C# 7.3
Next steps for pattern matching?
C# 8.0
Major features
http://www.c-sharpcorner.com/article/c-sharp-7-2-new-features-with-visual-studio-2017/
9. ASYNC MAIN
static void Main(string[] args)
{
MainAsync(args).Wait();
}
async static Task MainAsync(string[] args)
{
async static Task Main(string[] args)
{
Old Style New Style
10. public static void OutOldStyle(string @int)
{
int tmpInt = default(int);
int.TryParse(@int, out tmpInt);
Console.WriteLine(tmpInt);
}
OUT VARIABLES
Declare out variable inline
public static void OutNewStyle(string @int)
{
int.TryParse(@int, out int tmpInt);
Console.WriteLine(tmpInt);
}
11. DEFAULT LITERAL EXPRESSION
public static void OutOldStyle(string @int)
{
// Ugly formality
int tmpInt = default;
int.TryParse(@int, out tmpInt);
Console.WriteLine(tmpInt);
}
13. THROW EXPRESSIONS
You can throw exceptions in code constructs that previously were not allowed
because throw was a statement
Null coalescing expressions
Some lambda expressions
Expression-bodied
14. // Tuples Old C# Style
var tuple = new Tuple<int, int>(1, 2);
var sum = new Tuple<int, int>(1, 20);
var first = sum.Item1;
var count = sum.Item2;
Console.WriteLine($"item1 {sum.Item1} item2 {sum.Item2}");a
// Tuples C# 7 Style
var tupleNew = (1, 2);
var sumNew = (first: 1, count: 20);
Console.WriteLine($"first {sumNew.first} count {sumNew.count}");
TUPLES
A tuple is a immutable data structure that has a specific number and sequence of
elements
ValueTuple
15. DECONSTRUCT
Deconstruct an object to a tuple struct Point
{
public static Point parse(string coordinate)
{
}
public void Deconstruct(out int x, out int y)
{
x = X; y = Y;
}
}
var (x1, y1) = Point.parse(coordinate);
18. PATTERN MATCHING
Pattern matching (similar to a `switch`
statement that works on the “shape” of
the data, for example its type, rather
than just the value)
Constant patterns
Type patterns
Var patterns
// C# 6
var cSharpOld = string.Empty;
var str = cSharpOld as string;
if (str != null)
{
// Code that uses str
};
// C# 7
if (cSharpOld is string strTmp)
{
// Code that uses strTmp
};
19. LOCAL FUNCTIONS
Nesting functions inside other functions to limit their scope and visibility
Better performance
Reduced memory pressure
20. var array = new[] { 1, 2, 3, 4, 5};
ref int GetItem(int[] arrayParam, int
index) => ref arrayParam[index];
ref int item = ref GetItem(array, 1);
REF RETURNS
21. GENERALIZED ASYNC RETURN I
Define custom return types on async methods
ValueTask
Designed for the very scenario
22. BINARY LITERALS & DIGITS
SEPARATORS
New tokens improve readability for numeric constants
int binary = 0b1001_1010_1001_0100;
int hex = 0x1c_a0_41_fe;
double real = 1_00.99_9e-1_000;
24. C# 8.0: ASYNC STREAMS AND
DISPOSABLES
IAsyncEnumerable<Person> people = database.GetPeopleAsync();
foreach await (var p in people) { … }
using await (IAsyncDisposable resource = await store.GetRecordAsync(…)) { … }
25. C# 8.0: EXTENSION EVERYTHING
extension Enrollee extends Person
{
// static field
static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>();
// instance method
public void Enroll(Professor supervisor) { enrollees[this] = supervisor; }
// instance property
public Professor Supervisor => enrollees.TryGetValue(this, out var supervisor) ?
supervisor : null;
// static property
public static ICollection<Person> Students => enrollees.Keys;
// instance constructor
public Person(string name, Professor supervisor) : this(name) {
this.Enroll(supervisor); }
}
26. C# 8.0: RECORDS
class Person : IEquatable<Person>
{
public string First { get; }
public string Last { get; }
public Person(string First, string Last) => (this.First, this.Last) = (First, Last);
public void Deconstruct(out string First, out string Last)
=> (First, Last) = (this.First, this.Last);
public bool Equals(Person other)
=> other != null && First == other.First && Last == other.Last;
public override bool Equals(object obj) => obj is Person other ? Equals(other) : false;
public override int GetHashCode() => GreatHashFunction(First, Last);
…
}
class Person(string First, string Last);
29. C# 1.0 – THE “MANAGED” RELEASE
Reference Types
Value Types
Primitive Types
Struct
Class, Inheritance and Polymorphism
Properties
Namespace
Enum
Delegates
Events
Exceptions
Enumerators
Attributes
30. REFERENCE TYPES
Una qualsiasi dichiarazione di tipo fatta con la parola class indica un Reference Type
Il riferimento è a una istanza di quel tipo
L’istanza viene creata con l’operatore new
Allocazione nel managed heap
L’assegnazione tra variabili di tipo Reference implica la copia del riferimento, non dell’oggetto
riferito
Una variabile di un reference type accetta null
Invalida il riferimento
Valore di default per una variabile
Non distrugge l’oggetto (Garbage Collection)
Far riferimento ad una variabile null solleva una NullReferenceException
Gli array e le stringhe sono reference types
22/10/2017 MARCO PARENZAN 30
31. VALUE TYPES
Nel caso di local variables, parameters, loop counters, un programma ne può fare un uso
intensivo
Problemi
Allocazione
Accesso
Rilascio
Uso dello stack
Allocazione e rilascio automatico
Accesso alla memoria efficiente
I value types contengono i valori direttamente, non i riferimenti
Int, char, byte, TimeSpan sono value types primitivi
Se ne possono definire di custom tramite struct
22/10/2017 MARCO PARENZAN 31
32. TIPI PRIMITIVI
I tipi primitivi sono strutture definite nel namespace System
È possibile usare il loro nome o il loro
alias C#
22/10/2017 MARCO PARENZAN 32
Int32 i = 4;
int j;
j = i;
structure name
C# alias
bool Boolean
char Char
sbyte SByte
byte Byte
short Int16
ushort UInt16
int Int32
uint UInt32
long Int64
ulong UInt64
float Single
double Double
decimal Decimal
Boolean
character
integer
floating point
same type so
can interoperate
33. STRUCT
Possono avere proprietà, metodi, costruttori, membri, implementare interfacce
Non possono:
Ereditarietà per classe
Valori inizializzati alla definizione
Non possono avere un custom default constructor (senza parametri)
Un costruttore deve esplicitamente inizializzare tutte le variabili
22/10/2017 MARCO PARENZAN 33
34. CLASS(I) E EREDITARIETÀ
Class per definire reference type
Ereditarietà
Single rooted
Multiple Interface
“base” per referenziare la classe base
Le classi non sono polimorfiche di default
I membri non sono virtuali di default
Necessaria la parola chiave virtual
Per identificare un tipo si usa l’operatore is
<variable> is <type>
22/10/2017 MARCO PARENZAN 34
35. PROPRIETÀ
Le proprietà combinano la sintassi delle variabili membro con il controllo delle
funzioni membro
Permettono di associare ad un nome (con un tipo) le due funzioni accessorie
Syntactic Sugar
Permettono di definire
Readonly properties
Guarded properties
Calculated properties
22/10/2017 MARCO PARENZAN 35
36. NAMESPACE
Qualificano un insieme di classi sotto un unico nome contenitore
Nome COMPLETO della classe: nome del namespace + nome della classe
Livelli>1
Si definiscono in namespace {}
Permettono di disambiguare classi con lo stesso nome
È possibile usare sempre i nomi qualificati
È possibile importare un namespace con la parola chiave using
Permette di definire alias sul namespace: using <alias> = <namespace>
<alias>.<nome classe>
Permette di definire alias sulla classe: using <aliasclasse> = <namespace>.<classe>
<aliasclasse>
È possibile usare la parola using sia dentro che fuori del namespace
La differenza diventa “importante” nel caso nello stesso file ci siano più definizioni di namespace
Spesso non succede
Esiste un “global” namespace
22/10/2017 MARCO PARENZAN 36
37. ENUM
La parola chiave enum è usata per definire il nuovo tipo
Contiene un insieme di costanti simboliche
È possibile definire variabili di un tipo enum, usando I valori definiti in essa
Di default usa (implicitamente) il tipo int
È possibile fare il cast (esplicito) da/verso il tipo implicito
È possibile specificare un altro tipo primitivo (a parte char)
È possibile assegnare dei valori diretti
È possibile modificare la sequenza dei numeri
22/10/2017 MARCO PARENZAN 37
38. DELEGATE
La parola riservata delegate serve a definire un tipo in grado di puntare a un metodo e gestire indirettamente
la sua invocazione.
Possiamo vedere un delegate come un "puntatore a funzione“
Garantisce che il metodo abbia una specifica firma
Lista ordinata dei tipi dei parametri formali
Non include il tipo di ritorno (ma due funzioni non possono distinguersi per il solo tipo di ritorno)
Offrono la possibilità di chiamare un metodo (anche) in modo asincrono tramite BeginInvoke e EndInvoke
Un delegato ha dei metodi (è una classe)
<delegate>() è la sintassi contratta di <delegate>.Invoke()
I delegati sono multicast
È possibile assegnare ad un delegate più puntamenti a metodi diversi
Un invocazione sul delegato implica la chiamata a tutti i metodi referenziati
Vengono utilizzati principalmente per:
la gestione degli eventi
L’uso come callback (passare un metodo come “valore” ad un altro metodo)
22/10/2017 MARCO PARENZAN 38
39. EVENTI
Un evento caratterizza un componente
Qualcosa che succede all’interno del componente e che lo stesso notifica
Un oggetto esterno può sottoscrivere l’evento per essere notificato quando succede
Un evento è una specializzazione di un delegato
event è una parola chiave da associare ad una proprietà di un tipo delegato
event impedisce l’uso dell’assegnazione (“=“) ma solo la sottoscrizione (“+=“) o la cancellazione (“-=“)
Il mancato uso dell’assegnazione impedisce ad un consumatore generico di rimuovere la sottoscrizione a qualche altro
componente
Qualsiasi delegato può essere usato per un evento
È convenzione usare un delegato del tipo
delegate void <event handler>(object sender, <event args> e)
dove <event args> è una classe che deriva da EventArgs
È possibile creare una variabile membro di tipo evento
È possibile creare una proprietà di tipo evento
Rispetto alle proprietà le funzioni accessorie sono add e remove
22/10/2017 MARCO PARENZAN 39
40. ECCEZIONI
Un’eccezione è un evento sincrono
È prevedibile il punto in cui può avvenire, non il momento
Un’eccezione è un pattern utilizzato per notificare errori
Un’eccezione può essere gestita con un blocco try…catch…finally
Try: blocco che può generare eccezione
Catch: blocco eseguito subito dopo all’istruzione nel blocco try che ha generato l’eccezione
Finally: blocco eseguito comunque dopo il blocco try e l’eventuale blocco catch
Un’eccezione, per essere gestita dal blocco try prende forma di un oggetto che deriva dalla classe exception
La notifica di un’eccezione si basa sullo stack
Un blocco try…catch…finally viene registrato nello stack
Non è detto che un metodo che chiama un altro metodo che genera una eccezione debba “trappare” una eccezione
Viene fatto uno “stack walk” per trovare il primo blocco disponibile
Eventualmente quello di default fornito dal framework
È possibile definire una eccezione derivando una nuova classe dal tipo Exception
Si usa l’istruzione throw per sollevare una nuova eccezione
Ci sono delle eccezioni di uso comune
22/10/2017 MARCO PARENZAN 40
41. ECCEZIONI COMUNI
System.ArgumentException
Thrown when a function is called with a bogus argument. This generally indicates a program bug.
System.ArgumentNullException
Thrown when a function argument is (unexpectedly) null. (It is a subclass of ArgumentException.
System.ArgumentOutOfRangeException
Thrown when a (usually numeric) argument is too big or too small. (It is also a subclass of ArgumentException.) For example, this is thrown when passing a negative
number into a function that accepts only positive values.
System.InvalidOperationException
Thrown when the state of an object is unsuitable for a method to successfully execute, regardless of any particular argument values. Examples include reading an
unopened file or getting the next element from an enumerator where the underlying list has been modified partway through the iteration.
System.NotSupportedException
Thrown to indicate that a particular functionality is not supported. A good example is calling the Add method on a collection for which IsReadOnly returns true.
System.NotImplementedException
Thrown to indicate that a function has not yet been implemented.
System.ObjectDisposedException
Thrown when the object upon which the function is called has been disposed.
22/10/2017 MARCO PARENZAN 41
42. ENUMERATORI
Un enumeratore è un cursore read-only forward only
Permette di visitare una collezione di elementi
Si basa su due interfacce
IEnumerator: l’enumeratore vero e proprio
IEnumerable: permette di richiedere ad una collezione un enumeratore per visitare la stessa
Usato dal costrutto foreach
22/10/2017 MARCO PARENZAN 42
43. ATTRIBUTI
Permettono di associare metadati agli elementi di definizione di una classe (classe, metodo,
variabile, proprietà, …)
Sono informazioni disponibili a runtime tramite reflection
<object>.GetType().GetMember()
Permettodo di implementare algoritmi basati sulla struttura stessa della classe, decidendo in base
agli attributi
Un esempio su tutti: serializzazione
Atttributi Standard (dalla BCL)
Attributi Custom
Classi derivate da System.Attribute
Accessibili tramite Attribute.GetCustomAttribute(<memberinfo>)
Sintassi:
[<attribute>Attribute(positional parameters, named parameters….)]
22/10/2017 MARCO PARENZAN 43
46. STATIC CLASSES
Contengono solo metodi statici
Non membri di istanza
Serviranno per gli Extension Methods
22/10/2017 MARCO PARENZAN 46
public static class Math
{
public static double Sin(double x) {…}
public static double Cos(double x) {…}
…
}
47. GENERICS
Cosa sono i generics?
Polimorfismo Parametrico
Funziona sia con reference and value types
Controllo dei tipi in fase di dichiarazione
No boxing (value types)
No downcasts (no object)
Supporto completo a runtime
Reduced code bloat
Non bisogna scrivere classi wrapper tipizzate
22/10/2017 MARCO PARENZAN 47
48. COME POSSONO ESSERE USATI?
Con varie definizione di tipo
Class, struct, interface and delegate
Per specificare variabili membro, parametri, valori di ritorno
22/10/2017 MARCO PARENZAN 48
50. VARIOUS OTHER GENERIC CLASSES
System.Collections.ObjectModel classes
Collection<T>
KeyedCollection<T>
ReadOnlyCollection<T>
Various Other Classes
Nullable<T>
EventHandler<T>
Comparer<T>
22/10/2017 MARCO PARENZAN 50
51. NULLABLE TYPES
Int è un value type e non può accettare il null (reference type)
Utile nel momento in cui mappiamo gli attributi di una tabella di database (tutti gli attributi di una tabella
di DB possono essere nullabili)
Applicazione dei generics
Nullable<T>
T è un tipo primitivo (value type/struct)
Rende possibile la sintassi
int? x = null;
Int? è equivalente a Nullable<int>
Il cast può essere:
Implicito: int? x = 5;
Esplicito: int y = (int) x; // perché bisogna verificare se non sia null
int y = 0;
if (x.HasValue) y = (int) x;
22/10/2017 MARCO PARENZAN 51
52. TIPI PARZIALI (PARTIAL TYPES)
È possibile spezzare una dichiarazione in più files
Utile quando c’è un designer/generatore di codice
Ottimo anche per organizzare il codice
Una partial class per ogni interfaccia implementata
Tipi supportati
Classes (Partial Classes)
Struct
Interface
Divisi a design time, “fusi insieme” a compile time
22/10/2017 MARCO PARENZAN 52
53. ANONYMOUS METHODS
Permettono di definire direttamente il codice dove è necessario un delegato
Il tipo dei delegati viene automaticamente inferenziato (non serve istanziare
esplicitamente il delegato, ma scrivere solo il corpo)
22/10/2017 MARCO PARENZAN 53
button.Click += delegate(object sender, EventArgs e) {
MessageBox.Show(((Button)sender).Text);
};
54. ANONYMOUS METHODS
I blocchi di codice possono accedere alle variabili locali
Non possono però accedere a parametri (di un metodo in cui sono definiti) ref o out
Ovvio, in quanto la loro esecuzione non è legata all’invocazione del metodo di definizione
La vita delle variabili locali è “estesa” fino a che il delegato che le referenzia non è
eligibile di garbage collection
Tutto è dovuto a generazione nascosta di classi
22/10/2017 MARCO PARENZAN 54
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n);
};
55. ITERATORI
È possibile usare la parola chiave yield
yield return e yield break
Bisogna restituire IEnumerator o IEnumerable
22/10/2017 MARCO PARENZAN 55
public class List
{
public IEnumerator GetEnumerator() {
for (int i = 0; i < count; i++) {
yield return elements[i];
}
}
}
57. C# 3.0 – THE “FUNCTIONAL”
RELEASE
Implicitly typed local variables
Object and collection initializers
Auto-properties
Anonymous types
Extension methods
Query expressions
Lambda expressions
Expression trees
58. AUTOIMPLEMENTED PROPERTIES
Permettono di specificare una proprietà senza doverne specificare il field privato
Velocizza il processo di creazione di proprietà all’interno delle classi
Il membro privato viene generato a compile-time
Per vedere il nome del field privato generato, è necessario utilizzare ildasm.exe o
Reflector.exe
Non è possibile utilizzarle per specificare proprietà in read-only o write-only
E’ possibile limitare l’accesso al get o al set di una proprietà, specificandone la visibilità
Non è possibile specificare un valore di default a causa del membro privato che non è
presente
Nel costruttore della classe si può intervenire impostando il valore di default
22/10/2017 MARCO PARENZAN 58
59. OBJECT INITIALIZERS
È possibile inizializzare variabili membro e proprietà, senza richiamare il costruttore
in modo esplicito
new C(1, 2, name=“my class”);
Valgono le regole di visibilità
È possibile fare annidamento
Initializzare grafi
Collection initializers
List<int> digits = new List<int> { 0, 1};
Deve implementare System.Generic.ICollection<T>
Object initializers
var a = new Point { X = 0, Y = 1 };
22/10/2017 MARCO PARENZAN 59
60. IMPLICITLY TYPED VARIABLES
E’ possibile dichiarare le variabili in modo implicito, utilizzando la parola chiave “var”
var i = 5;
var s = "Hello";
var d = 1.0;
var orders = new Dictionary<int,Order>();
Il tipo delle variabili è indotto dalla espressione che lo inizializza
DEVE INCLUDERE L’INIZIALIZZAZIONE
“var” non è variant o object
È comunque statically typed
Non può essere null
Var può essere usata SOLO nei metodi
Non può essere usata a livello di classe
Attenzione all’abuso
Bisogna capire il contesto dell’esecuzione per capire cosa c’è dentro
E’ possibile utilizzare la keywork “var” anche all’interno di cicli for e foreach
In VBOption Infer On
22/10/2017 MARCO PARENZAN 60
61. ANONYMOUS TYPES
È una “tupla” le cui proprietà specifiche sono inferenziate tramite Object Initializer
Viene fatto a compile time, quindi è sempre comunque statically/strongly typed
Internamente viene creata una classe nascosta
var x = new {p1 = 10, p2 = “name”};
Il tipo di x è anonimo
Non è possibile referenziarlo “per nome” da codice
structural type equivalence
Due tipi anonimi possono essere compatibili
Viene ricostruita la “compatibilità” a compile time
Viene definito un solo nuovo tipo (anonimo)
La classe verrà generata automaticamente in fase di compilazione, e deriverà da System.Object
implicitly typed arrays
var a = new[] { 1, 10, 100, 1000 };
Devono avere tipi compatibili
O conversioni implicite
22/10/2017 MARCO PARENZAN 61
63. EXTENSION METHODS
È possibile aggiungere metodi a classi già definite
È possibile aggiungere metodi a classi già compilate, in assembly diversi
Non sono mixin (dai dynamic languages)
Sono “syntactic sugar”
Readability
Solo metodi
Non per properties, events, operators (almeno per adesso)
Metodi statici in classi statiche
La chiamata esplicita al metodo statico avviene sempre (e rimuove ambiguità)
Nel caso di sovrapposizione con metodi locali
I metodi locali hanno la precedenza
L’inserimento degli extension method avviene al momento dell’importazione del namespace
22/10/2017 MARCO PARENZAN 63
64. PARTIAL METHODS
E’ stata aggiunta la possibilità di definire un metodo come “partial”
Permette di definire un metodo in una parte della classe, e poterlo implementare in un’altra
parte della classe
Utile in caso di uso dei generatori di codice
Non necessità di ereditarietà di metodi virtuali
I metodi dichiarati come “partial” hanno delle limitazioni:
Devono essere definiti all’interno di una partial class
Devono sempre ritornare void
Possono avere argomenti, ma non con clausula “out”
Sono sempre implicitamente privati
Se un metodo partial non viene implementato, questo non compare nel codice compilato
(nemmeno la chiamata del metodo)
22/10/2017 MARCO PARENZAN 64
65. DELEGATE
La parola riservata delegate serve a definire un tipo in grado di puntare a un metodo e gestire indirettamente
la sua invocazione.
Possiamo vedere un delegate come un "puntatore a funzione“
Garantisce che il metodo abbia una specifica firma
Lista ordinata dei tipi dei parametri formali
Non include il tipo di ritorno (ma due funzioni non possono distinguersi per il solo tipo di ritorno)
Offrono la possibilità di chiamare un metodo (anche) in modo asincrono tramite BeginInvoke e EndInvoke
Un delegato ha dei metodi (è una classe)
<delegate>() è la sintassi contratta di <delegate>.Invoke()
I delegati sono multicast
È possibile assegnare ad un delegate più puntamenti a metodi diversi
Un invocazione sul delegato implica la chiamata a tutti i metodi referenziati
Vengono utilizzati principalmente per:
la gestione degli eventi
L’uso come callback (passare un metodo come “valore” ad un altro metodo)
22/10/2017 MARCO PARENZAN 65
66. EVENTI
Un evento caratterizza un componente
Qualcosa che succede all’interno del componente e che lo stesso notifica
Un oggetto esterno può sottoscrivere l’evento per essere notificato quando succede
Un evento è una specializzazione di un delegato
event è una parola chiave da associare ad una proprietà di un tipo delegato
event impedisce l’uso dell’assegnazione (“=“) ma solo la sottoscrizione (“+=“) o la cancellazione (“-=“)
Il mancato uso dell’assegnazione impedisce ad un consumatore generico di rimuovere la sottoscrizione a qualche altro
componente
Qualsiasi delegato può essere usato per un evento
È convenzione usare un delegato del tipo
delegate void <event handler>(object sender, <event args> e)
dove <event args> è una classe che deriva da EventArgs
È possibile creare una variabile membro di tipo evento
È possibile creare una proprietà di tipo evento
Rispetto alle proprietà le funzioni accessorie sono add e remove
22/10/2017 MARCO PARENZAN 66
67. ANONYMOUS METHODS
Permettono di definire direttamente il codice dove è necessario un delegato
Il tipo dei delegati viene automaticamente inferenziato (non serve istanziare
esplicitamente il delegato, ma scrivere solo il corpo)
22/10/2017 MARCO PARENZAN 67
button.Click += delegate(object sender, EventArgs e) {
MessageBox.Show(((Button)sender).Text);
};
68. ANONYMOUS METHODS
I blocchi di codice possono accedere alle variabili locali
Non possono però accedere a parametri (di un metodo in cui sono definiti) ref o out
Ovvio, in quanto la loro esecuzione non è legata all’invocazione del metodo di definizione
La vita delle variabili locali è “estesa” fino a che il delegato che le referenzia non è
eligibile di garbage collection
Tutto è dovuto a generazione nascosta di classi
22/10/2017 MARCO PARENZAN 68
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n);
};
69. LAMBDA EXPRESSIONS
Permettono di definire delle funzioni “inline”, associando direttamente un blocco di codice
Permettono di creare un metodo “stand-alone” all’interno del codice (utilizzando gli anonymous methods)
Sono un’ulteriore semplificazione rispetto l’uso dei delegate
Dal calcolo lambda
x . x + 1
In C# 3.0
x => x + 1
Dalla sintassi delle anonymous functions
delegate(int x) { return x + 1;}
Possono usare variabili implicitamente tipizzate
Possono avere più di una variabile
Il corpo può contenere espressioni o istruzioni
22/10/2017 MARCO PARENZAN 69
70. ESEMPI DI LAMBDA EXPRESSIONS
x => x + 1
// Implicitly typed, expression body
x => { return x + 1; }
// Implicitly typed, statement body
(int x) => x + 1
// Explicitly typed, expression body
(int x) => { return x + 1; }
// Explicitly typed, statement body
(x, y) => x * y
// Multiple parameters
() => Console.WriteLine()
// No parameters
22/10/2017 MARCO PARENZAN 70
71. LAMBDA TO DELEGATES
Una lambda expression è un valore,che non ha tipo, ma può essere convertito in un particolare delegato
delegate R Func<A,R>(A arg);
Func<int,int> f1 = x => x + 1;
// Ok
Func<int,double> f2 = x => x + 1;
// Ok
Func<double,int> f3 = x => x + 1;
// Error – double cannot be
// implicitly converted to int
Nel framework sono predefiniti dei delegates “standard”
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T a);
public delegate TResult Func<T1, T2, TResult>(T1 a, T2 b);
public delegate TResult Func<T1, T2, T3, TResult>(T1 a, T2 b, T3 c);
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 a, T2 b, T3 c, T4 d);
public delegate void Action();
public delegate void Action<T>(T a);
public delegate void Action<T1, T2>(T1 a, T2 b);
public delegate void Action<T1, T2, T3>(T1 a, T2 b, T3 c);
public delegate void Action<T1, T2, T3, T4>(T1 a, T2 b, T3 c, T4 d);
22/10/2017 MARCO PARENZAN 71
72. EXPRESSION TREES
Forniscono una rappresentazione ad oggetti di
una lambda expression.
Sono assimilabili agli AST generati da un
compilatore per creare il codice “a compiler
time”
L’expression tree è accessibile a runtime
Le lambda expression possono essere
convertite in un expression tree
Expression<Func<T>> e = x => x + 1;
Sono compilati, strong-typed, provider
independent e serializzabili.
Sono Immutabili, e quindi per modificarne una
sua parte, si deve creare un nuovo Expression
Tree
22/10/2017 MARCO PARENZAN 72
73. VISITA E COSTRUZIONE
DI UN EXPRESSION TREE
// Create an expression tree.
Expression<Func<int, bool>> exprTree = num => num < 5;
// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;
Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",
param.Name,left.Name, operation.NodeType, right.Value);
/* This code produces the following output:
Decomposed expression: num => num LessThan 5
*/
// Create the parameter "x" in x + 1
ParameterExpression p0 = Expression.Parameter(typeof(int),"x");
// Create the constant 1 in x + 1
ConstantExpression c0 = Expression.Constant(1);
// Build the addition expression x + 1 using the above
// Note it will really look like Add(x,1)
BinaryExpression expression = Expression.Add(p0, c0);
// Create the Lamda Expression x => Add(x,1)
var lambdaExpression = Expression.Lambda<Func<int,int>>(expression, new ParameterExpression[]{ p0 });
// Let's compile it so we can use it
var theDelegate = lambdaExpression.Compile();
// Execute... 6 + 1 = 7
var seven = theDelegate.Invoke(6);
22/10/2017 MARCO PARENZAN 73
75. C# 4.0 – THE “INTEROPERABILITY”
RELEASE
Dynamic binding
Dynamic Languages interoperability
COM interoperability
Named and optional parameters
Generic co- and contravariance
76. DYNAMIC SUPPORT
È l’implementazione in C# del “Late Binding”, ora chiamato “dynamic binding”
VB ce l’ha sempre avuto!
Differenza MetodologicaMolti VB-ers dimenticano di impostare in un nuovo
progetto (o modulo) prima di tutto “Option Strict On”
…e il progetto è INTERAMENTE Option Strict On, mentre dynamic solo quella variabile
Differenza Tecnologica
È una generalizzazione del meccanismo del VB
Vale solo per se stesso
È una evoluzione della Reflection
È una evoluzione di altre API (ICustomTypeDescriptor)
DLR
22/10/2017 MARCO PARENZAN 76
77. DYNAMIC LANGUAGE RUNTIME
22/10/2017 MARCO PARENZAN 77
Python
binder
Ruby
binder
COM
binder
JavaScript
binder
Object
binder
Dynamic Language Runtime
Expression Trees Dynamic Dispatch Call Site Caching
IronPython IronRuby C# VB.NET Others…
78. CLR EVOLUTION
22/10/2017 MARCO PARENZAN 78
.NET4.0
.NET3.5
DLR2
LINQ
DLR
Language
features
Expression
trees
Expression
trees v2
Call site
caching
Dynamic
dispatch
Silverlight
.NET2.0
Generics
Fast
delegates
Dynamic
methods
Script
hosting
Compiler as
a Service
.NET1.0
GC
BCL
ReflectionJIT
Code
generation
Verifier
sandbox
79. DYNAMIC @ WORK
22/10/2017 MARCO PARENZAN 79
Calculator calc = GetCalculator();
int sum = calc.Add(10, 20);
object calc = GetCalculator();
Type calcType = calc.GetType();
object res = calcType.InvokeMember("Add",
BindingFlags.InvokeMethod, null,
new object[] { 10, 20 });
int sum = Convert.ToInt32(res);
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);
Statically typed to
be dynamic
Dynamic method
invocation
Dynamic
conversion
80. OPTIONAL AND
NAMED PARAMETERS
Optional parameters
Poter definire alcuni parametri opzionali senza dover creare tanti metodi sovraccarichi per
distinguere la firma
Anche questo il VB ce l’aveva già!!!!!!!!!
Named parameters
Conseguenza degli optional parameters
Poter valorizzare alcuni parametri e non altri, in una sequenza arbitraria
22/10/2017 MARCO PARENZAN 80
81. CO- AND CONTRA-VARIANCE
22/10/2017 MARCO PARENZAN 81
void Process(object[] objects) { … }
string[] strings = GetStringArray();
Process(strings);
void Process(object[] objects) {
objects[0] = "Hello"; // Ok
objects[1] = new Button(); // Exception!
}
List<string> strings = GetStringList();
Process(strings);
void Process(IEnumerable<object> objects) { … }
.NET arrays are
co-variant
…but not safely
co-variant
Until now, C#
generics have
been invariant
void Process(IEnumerable<object> objects) {
// IEnumerable<T> is read-only and
// therefore safely co-variant
}
C# 4.0 supports
safe co- and
contra-variance
82. SAFE CO- AND CONTRA-VARIANCE
22/10/2017 MARCO PARENZAN 82
public interface IEnumerable<T>
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<T>
{
T Current { get; }
bool MoveNext();
}
public interface IEnumerable<out T>
{
IEnumerator<T> GetEnumerator();
}
public interface IEnumerator<out T>
{
T Current { get; }
bool MoveNext();
}
out = Co-variant
Output positions only
IEnumerable<string> strings = GetStrings();
IEnumerable<object> objects = strings;
Can be treated as
less derived
public interface IComparer<T>
{
int Compare(T x, T y);
}
public interface IComparer<in T>
{
int Compare(T x, T y);
}
IComparer<object> objComp = GetComparer();
IComparer<string> strComp = objComp;
in = Contra-variant
Input positions only
Can be treated as
more derived
83. TYPE EMBEDDING
Type Embedding
Visual Studio option enabling Type Embedding of assembly references
Interfaces with the same GUID are treated by CLR as equivalent types
Only metadata is locally embedded
interfaces (must have ComImport, Guid attributes)
delegates
simple structs
enums
But not classes or static methods
Typical applications use helper libraries
Helper libraries also need to embed types
Number of separate copies of the same interop type are created
Yes, these all are different types!
Can we still use a method returning a different copy of a type ?
22/10/2017 MARCO PARENZAN 83
84. TYPE EQUIVALENCE
Interfaces with the same GUID are treated by CLR as equivalent types
Casts to an equivalent interface
CLR looks for TypeIdentifier attribute to be present on one of the interfaces
Calls through an equivalent interface
COM objects: CLR intercepts the calls and routes them through COM interop (this is the old
behavior)
Managed objects: CLR finds an equivalent interface in the inheritance chain, looks up a method
with the same vtable offset, and verifies the signatures match
22/10/2017 MARCO PARENZAN 84
85. TYPE EMBEDDING
AND TYPE EQUIVALENCE
Future versioni del CLR, C# e VB.NET sfrutteranno meglio queste capacità
http://channel9.msdn.com/shows/Going+Deep/Raja-Krishnaswamy-and-Vance-Morrison-CLR-4-
Inside-Type-Equivalence/
22/10/2017 MARCO PARENZAN 85
91. THE NAMEOF() OPERATOR (CONT)
We can hard-code, but if we rename the variable, we have to remember to update
the string:
92. THE NAMEOF() OPERATOR (CONT)
Now, you can get a string representation of an identifier with nameof():
93. AUTO-PROPERTY INITIALIZATION
Before, if you wanted to default an auto-property to a non-default value, there
wasn’t a simple way.
Either:
Create a backing field with initializer, then wrap in property
Or create an auto-property and then assign a value in the constructor
This should really be a simple, one-step process.
98. INDEXED INITIALIZATION LISTS
Initializer lists now allow you to use indexers if the container supports them.
For example, you used to have to initialize a dictionary like this:
99. INDEXED INITIALIZATION LISTS
(CONT)
But now you can use the indexer syntax instead:
The syntax is much cleaner and clearly identifies which string is the key and which is
the value.
100. INDEXED INITIALIZATION LISTS
(CONT)
Warning: just because a container supports indexing doesn’t mean initializing with it
will always be logically sound…
For example:
What’s wrong with this?
101. INDEXED INITIALIZATION LISTS
(CONT)
It is legal and compiles with no errors.
However, you are attempting to set elements that are beyond the list size, which
List<T> doesn’t allow.
This is the same as doing this:
102. INDEXED INITIALIZATION LISTS
(CONT)
So remember, it’s just syntactical sugar, it won’t stop you from performing a run-time
illegal action.
To make that example work, you’d have to do something like:
103. THE USING STATIC DIRECTIVE
There are many static methods where the enclosing class mainly acts as an
organization point (e.g. Math).
Sometimes, these class names give context to the static member being called.
Other times, they become repetitive clutter.
The using static declaration allows you to import the static members of a type into
your namespace.
Also allows you to limit extension methods imported.
104. THE USING STATIC DIRECTIVE
(CONT)
Consider the following:
A lot of these class names we can assume from context or are just organizational
clutter.
105. THE USING STATIC DIRECTIVE
(CONT)
If our program is a console app, we can probably assume the Console.
Similarly, the Math and Enumerable classes don’t add much. We already know what
Pow() and Range() do.
Now, we can import the static members of these types with using static:
106. THE USING STATIC DIRECTIVE
(CONT)
This would simplify our code to be:
We’ve removed a lot of redundant code without obscuring the clarity.
107. THE USING STATIC DIRECTIVE
(CONT)
It’s not just for classes, you can import the static members of structs or enums.
For example, doing this:
Would allow us to do this:
108. THE USING STATIC DIRECTIVE
(CONT)
Warning: just because you can do this doesn’t mean you always should.
Consider if you ran across this code:
There’s no context, so what the heck are we creating?
Here, the type would have given meaningful context:
110. METHOD AND PROPERTY
EXPRESSIONS (CONT)
You can now simplify with lambda expression syntax:
Handy for simple get-only properties, reduces the boilerplate around the get { }
syntax.
Somewhat reduces syntax burden on methods.
111. STRING INTERPOLATION
Consider building a string in a single statement with multiple components.
Typically we either use concatenation:
Or string formatting:
112. STRING INTERPOLATION (CONT)
The problem with concatenation is that it breaks up the flow of the string you are
building and makes it harder to envision the result.
Formatting helps solve this, but it removes the actual values from the string and
makes it harder to visualize where the arguments will be placed.
In addition, if you specify the wrong indexes of placeholders you will get a runtime
error.
113. STRING INTERPOLATION (CONT)
String interpolation fixes this, it allows us to use the actual values as the placeholders
inside the string.
You simply use $ as a string prefix to signal the compiler to use interpolation, then
enclose the values with curly brackets.
Behind the scenes, the compiler will generate the appropriate string format
expression for you.
Gives you all the power of string formatting, with ability to visualize the values in the
string itself.
116. ENHANCED EXCEPTION FILTERING
(CONT)
Standard exception filtering is fine when you just care about the type of the
exception thrown.
If you needed to make a decision to catch or not based on logic – instead of type --
it’s clunky.
For example, let’s assume we are dealing with a data layer that throws a dependency
exception with an IsRetryable property.
You may want to catch and handle if the exception is retryable, but let it bubble up if
not.
121. ENHANCED EXCEPTION FILTERING
(CONT)
Filtering conditions do not have to involve the exception, they can be any condition.
Filters are checked in order for the same type, this means that an unfiltered catch for
a type must be after all filtered catches for that type.
Filter only evaluated if that exception type is thrown.
If exception does not meet the filter, it is not rethrown behind the scenes, it is simply
not caught.
122. NULL CONDITIONAL OPERATOR
Have you ever consumed a web method (or other API) with a deeply nested
response?
To be safe you have to do several layers of null checks before getting to what you
really want to check:
123. NULL CONDITIONAL OPERATOR
(CONT)
C# 6 adds a new null conditional operator (?.) to access a member if not null, or
cascade if null.
This would make our logic:
In the above example, if response is null, or response.Results is null, the whole result
will be null.
124. NULL CONDITIONAL OPERATOR
(CONT)
Note that all of these are legal, but different:
The first throws if response null but cascades if Results is null, the second cascades if
response is null but throws if Results is null, the third cascades both.
125. NULL CONDITIONAL OPERATOR
(CONT)
A null-cascade that results in a value type will result in a nullable value type:
Though you can couple with the null-coallescing operator (??) to provide a default if
null.
128. NULL CONDITIONAL OPERATOR
(CONT)
So what if you want to check for null before invoking an indexer on an array, List<T>,
etc?
C# 6 has a syntax for null cascade on indexers (?[…]):
130. C# 6.0 THE “COMPILER REWRITE”
RELEASE
It’s been a black box
Re-write the compiler
Compiler written in C#
Easier to extend and maintain
Open Source!
.NET Compiler Platform
(a.k.a. Roslyn)
131. WHAT IS "ROSLYN"?
Normal compiler – traditionally black box
Source code in
Magic in between
Assemblies out
Nowadays we use
Intellisense
Refactoring
Code productivity tools
132. COMPILER'S PIPELINE
Traditional compiler pipeline
Parser – parses text to syntax objects
Symbols/Metadata – declarations are collected
Binder – identifiers, code flow bind to symbols
IL Emitter – IL assembly creation
134. WORKING WITH SYNTAX
Why – without text processing tools can:
See the structure of the source code
Create and rearrange source code
Contains
Syntax Trees
Syntax Nodes
Syntax Tokens
Syntax Trivia
Spans and Kinds
135. SYNTAX TREES
Primary structure for compilation
Hold all the source information
Constructs
Tokens
Everything!
Two-way communication with the source text
Immutable and thread-safe
Contains Nodes, Tokens, Trivia
136. SYNTAX TREES
Useful members
GetRoot()
GetText()
GetChanges()
Options
var code = File.ReadAllText("Code.cs");
var tree = SyntaxFactory.ParseSyntaxTree(code);
137. SYNTAX NODES
Primary element of Syntax Tree
Represents
Declarations
Statements
Clauses
Expressions
Each node has children – other nodes and tokens
138. SYNTAX NODES
Useful members
Modifiers
Type
Parent
DescendantNodes()
var localDeclarationNodes =
tree.GetRoot()
.DescendantNodes()
.OfType<LocalDeclarationStatementSyntax>();
139. SYNTAX TOKENS
Smallest syntactic fragment – no children
Represents
Keywords
Identifiers
Literals
Punctuation
var tokens = node.ChildTokens();
var token = tokens.First();
token.Value;
140. SYNTAX TRIVIA, SPANS, KIND
Syntax Trivia
Whitespace, comments, etc.
Spans
Position and number of characters within the source code
Kinds
Identifies the exact syntax element represented
Errors
Missing tokens or skipped tokens
141. COMPILATION
Compilation needs
Syntax Tree
Compilation Options
File Reference
var options = new
CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var reference = new
MetadataFileReference(typeof(object).Assembly.Location);
var compilation = CSharpCompilation.Create("Test")
.WithOptions(options)
.AddSyntaxTrees(tree)
.AddReferences(reference);
142. SEMANTIC MODEL
Additional semantic information for source code
Symbols at specific location
Resultant type of any expression
Errors and warnings
Variable flow in and out of source parts
143. SEMANTIC MODEL
var comp = CreateCompilation(tree, options, reference);
var model = comp.GetSemanticModel(tree);
var localDeclarationNodes = tree.GetRoot()
.DescendantNodes()
.OfType<LocalDeclarationStatementSyntax>();
foreach (var node in localDeclarationNodes)
{
var info = model.GetTypeInfo(node.Declaration.Type);
Console.WriteLine("{0} {1}", info.Type, node.Declaration);
}
144. EMITTING
Using the dynamically compiled result
Emit to memory stream
Load assembly from byte array
Use with normal reflection
using (var memory = new MemoryStream())
{
compilation.Emit(memory);
var assembly = Assembly.Load(memory.GetBuffer());
var type = assembly.GetType("NameOfType");
var instance = Activator.CreateInstance(type);
}
146. SUMMARY
C# 6 adds a lot of syntactical sugary goodness.
Some of the features are more powerful than others, but all have power to help increase
maintainability and readability of your code.
.NET Compiler Platform makes it easy for Microsoft to improve the language
A new wave to improve the language….