SlideShare a Scribd company logo
saturday 2017
WHAT’S NEW IN C# 7.X Marco Parenzan
@MARCO_PARENZAN
.NET, JavaScript,Azure ad IoT Developer, Trainer and Consultant
Microsoft MVP 2017 for Azure
Book Author @ Packt, LSWR
Community Lead per 1nn0va
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.
C# 7.0 THE DATA RELEASE
C# 7 OBJECTIVES
Working with data
 Pattern Matching
 Tuples
 Deconstruction
 Discards
Code Simplification
 Expression Bodied Properties, Constructor Finalizer
 Throw expression
 Out Variables
 Binary Literals and Digit separator
Improved Performances
 Local Functions
 Return values and local variables by reference
C# DESIGN
 github.com/dotnet/csharplang (definition)
 https://github.com/dotnet/roslyn (implementation)
 https://github.com/dotnet/cli
C# 7.2
https://github.com/dotnet/csharplang/tree/master/proposals/csharp-7.2
REF READONLY
CONDITIONAL REF
NON-TRAILING NAMED ARGUMENTS
PRIVATE PROTECTED
LEADING DIGIT SEPARATOR
SPAN SAFETY
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/
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
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);
}
DEFAULT LITERAL EXPRESSION
public static void OutOldStyle(string @int)
{
// Ugly formality
int tmpInt = default;
int.TryParse(@int, out tmpInt);
Console.WriteLine(tmpInt);
}
EXPRESSION-BODIED MEMBERS
C # 6 expression-bodied members expanded
Constructors
Finalizers
Indexers
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
// 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
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);
INFER TUPLE ELEMENT
var z = (x,y);
var xx = z.Item1; // 7.0
var xx = z.x; // 7.1+
DISCARDS
if (int.TryParse("4", out _))
{}
_ = stats(null);
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
};
LOCAL FUNCTIONS
Nesting functions inside other functions to limit their scope and visibility
Better performance
Reduced memory pressure
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
GENERALIZED ASYNC RETURN I
Define custom return types on async methods
ValueTask
Designed for the very scenario
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;
CONCLUSIONS
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(…)) { … }
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); }
}
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);
saturday 2017
Marco Parenzan
marco [dot] parenzan [at]
1nn0va [dot] it
@marco_parenzan
C# 1.0 – THE “MANAGED”
RELEASE
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
C# 2.0 – THE “OBJECT
MODEL” RELEASE
C# 2.0 – THE “OBJECT MODEL”
RELEASE
Generics
Partial types
Anonymous methods
Iterators
Nullable types
Getter/Setter separate accessibility
Static classes
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) {…}
…
}
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
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
GENERIC COLLECTIONS AND
INTERFACES
System.Collections.Generic classes
 List<ItemType>
 Dictionary<K,V>
 Stack<ItemType>
 Queue<ItemType>
System.Collections.Generic interfaces
 IList<ItemType>
 IDictionary<K,V>
 ICollection<ItemType>
 IEnumerable<ItemType>
 IEnumerator<ItemType>
 IComparable<OperandType>
 IComparer<OperandType>
22/10/2017 MARCO PARENZAN 49
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
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
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
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);
};
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);
};
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];
}
}
}
C# 3.0 – THE
“FUNCTIONAL” RELEASE
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
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
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
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 VBOption Infer On
22/10/2017 MARCO PARENZAN 60
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
XML LITERALS
VB only!
 Uno dei tanti divertissements….
22/10/2017 MARCO PARENZAN 62
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
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
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
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
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);
};
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);
};
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
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
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
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
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
C# 4.0 – THE
“INTEROPERABILITY” RELEASE
C# 4.0 – THE “INTEROPERABILITY”
RELEASE
Dynamic binding
 Dynamic Languages interoperability
 COM interoperability
Named and optional parameters
Generic co- and contravariance
DYNAMIC SUPPORT
È l’implementazione in C# del “Late Binding”, ora chiamato “dynamic binding”
 VB ce l’ha sempre avuto!
Differenza MetodologicaMolti 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
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…
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
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
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
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
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
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
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
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
C# 5.0 – THE
“ASYNCHRONOUS” RELEASE
C# 5.0 – THE “ASYNCHRONOUS”
RELEASE
Asynchronous methods
Caller info attributes
C# 6.0 THE “DECLARATIVE”
RELEASE
C# 6.0 THE “DECLARATIVE”
RELEASE
Auto-property initializers
Using Static Directive
Dictionary Initializer
Await in catch/finally
Exception filters
Exception filters
Expression-bodied members
Null propagation
String interpolation
nameof operator
THE NAMEOF() OPERATOR
Sometimes we want the name of an identifier as a string
THE NAMEOF() OPERATOR (CONT)
We can hard-code, but if we rename the variable, we have to remember to update
the string:
THE NAMEOF() OPERATOR (CONT)
Now, you can get a string representation of an identifier with nameof():
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.
AUTO-PROPERTY INITIALIZATION
(CONT)
Now instead of this:
AUTO-PROPERTY INITIALIZATION
(CONT)
Or this…:
AUTO-PROPERTY INITIALIZATION
(CONT)
We can now do this!
Reduces several lines of boiler-plating.
AUTO-PROPERTY INITIALIZATION
(CONT)
In addition, you can use it even if the property has no setter (i.e. a truly read-only
property):
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:
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.
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?
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:
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:
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.
THE USING STATIC DIRECTIVE
(CONT)
Consider the following:
A lot of these class names we can assume from context or are just organizational
clutter.
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:
THE USING STATIC DIRECTIVE
(CONT)
This would simplify our code to be:
We’ve removed a lot of redundant code without obscuring the clarity.
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:
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:
METHOD AND PROPERTY
EXPRESSIONS
Sometimes, we have properties or methods that are so simple, the body is mostly
boilerplate
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.
STRING INTERPOLATION
Consider building a string in a single statement with multiple components.
Typically we either use concatenation:
Or string formatting:
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.
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.
STRING INTERPOLATION (CONT)
So now, our example becomes:
In addition, all string formatting options are available:
ENHANCED EXCEPTION FILTERING
.NET has long had exception filtering:
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.
ENHANCED EXCEPTION FILTERING
(CONT)
Let’s assume our exception looks like this:
ENHANCED EXCEPTION FILTERING
(CONT)
To catch only retryable exceptions, we used to do this:
ENHANCED EXCEPTION FILTERING
(CONT)
Now, with C# 6, you can specify a logical filter as well:
ENHANCED EXCEPTION FILTERING
(CONT)
Now, you can have multiple catches on same type:
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.
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:
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.
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.
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.
NULL CONDITIONAL OPERATOR
(CONT)
The null conditional operator is not just for properties, you can use it for method
calls as well.
NULL CONDITIONAL OPERATOR
(CONT)
Also simplifies raising events:
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 (?[…]):
C# 6.0 THE “COMPILER
REWRITE” RELEASE
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)
WHAT IS "ROSLYN"?
Normal compiler – traditionally black box
 Source code in
 Magic in between
 Assemblies out
Nowadays we use
 Intellisense
 Refactoring
 Code productivity tools
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
WHAT IS "ROSLYN"?
Each phase now has corresponding API
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
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
SYNTAX TREES
Useful members
 GetRoot()
 GetText()
 GetChanges()
 Options
var code = File.ReadAllText("Code.cs");
var tree = SyntaxFactory.ParseSyntaxTree(code);
SYNTAX NODES
Primary element of Syntax Tree
Represents
 Declarations
 Statements
 Clauses
 Expressions
Each node has children – other nodes and tokens
SYNTAX NODES
Useful members
 Modifiers
 Type
 Parent
 DescendantNodes()
var localDeclarationNodes =
tree.GetRoot()
.DescendantNodes()
.OfType<LocalDeclarationStatementSyntax>();
SYNTAX TOKENS
Smallest syntactic fragment – no children
Represents
 Keywords
 Identifiers
 Literals
 Punctuation
var tokens = node.ChildTokens();
var token = tokens.First();
token.Value;
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
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);
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
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);
}
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);
}
CONCLUSIONS
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….

More Related Content

What's hot

2011.02.19 Introducing F#
2011.02.19 Introducing F#2011.02.19 Introducing F#
2011.02.19 Introducing F#
Marco Parenzan
 
Corso pratico di C# - 2013
Corso pratico di C# - 2013Corso pratico di C# - 2013
Corso pratico di C# - 2013
Matteo Valoriani
 
Introduzione a R
Introduzione a RIntroduzione a R
Introduzione a RMCalderisi
 
Pycrashcourse
PycrashcoursePycrashcourse
Pycrashcourse
rik0
 
Corso c++
Corso c++Corso c++
Corso c++
Antonio Furone
 
C# Language Evolution
C# Language EvolutionC# Language Evolution
C# Language Evolution
Marco Parenzan
 
Introduzione a scala prima parte
Introduzione a scala   prima parteIntroduzione a scala   prima parte
Introduzione a scala prima parte
Onofrio Panzarino
 
iContract
iContractiContract
iContract
guest891383
 
R Vectors
R VectorsR Vectors
R Vectors
Davide Rambaldi
 
Spyppolare o non spyppolare
Spyppolare o non spyppolareSpyppolare o non spyppolare
Spyppolare o non spyppolare
PyCon Italia
 
Lezione 10 (21 marzo 2012)2
Lezione 10 (21 marzo 2012)2Lezione 10 (21 marzo 2012)2
Lezione 10 (21 marzo 2012)2STELITANO
 
Object Oriented with Java Programmazione Base
Object Oriented with Java Programmazione BaseObject Oriented with Java Programmazione Base
Object Oriented with Java Programmazione Base
Felice Pescatore
 
OOP with C#
OOP with C#OOP with C#
OOP with C#
Manuel Scapolan
 

What's hot (20)

2011.02.19 Introducing F#
2011.02.19 Introducing F#2011.02.19 Introducing F#
2011.02.19 Introducing F#
 
Corso pratico di C# - 2013
Corso pratico di C# - 2013Corso pratico di C# - 2013
Corso pratico di C# - 2013
 
Introduzione a R
Introduzione a RIntroduzione a R
Introduzione a R
 
Pillole di C++
Pillole di C++Pillole di C++
Pillole di C++
 
Pycrashcourse
PycrashcoursePycrashcourse
Pycrashcourse
 
2006 Py03 intermedio
2006 Py03 intermedio2006 Py03 intermedio
2006 Py03 intermedio
 
Corso c++
Corso c++Corso c++
Corso c++
 
C# Language Evolution
C# Language EvolutionC# Language Evolution
C# Language Evolution
 
Introduzione a scala prima parte
Introduzione a scala   prima parteIntroduzione a scala   prima parte
Introduzione a scala prima parte
 
2008 python
2008 python2008 python
2008 python
 
2006 Py02 base
2006 Py02 base2006 Py02 base
2006 Py02 base
 
iContract
iContractiContract
iContract
 
R Vectors
R VectorsR Vectors
R Vectors
 
7 Sottoprogrammi
7   Sottoprogrammi7   Sottoprogrammi
7 Sottoprogrammi
 
Spyppolare o non spyppolare
Spyppolare o non spyppolareSpyppolare o non spyppolare
Spyppolare o non spyppolare
 
Il simulatore NS-2
Il simulatore NS-2Il simulatore NS-2
Il simulatore NS-2
 
8 Algoritmi
8   Algoritmi8   Algoritmi
8 Algoritmi
 
Lezione 10 (21 marzo 2012)2
Lezione 10 (21 marzo 2012)2Lezione 10 (21 marzo 2012)2
Lezione 10 (21 marzo 2012)2
 
Object Oriented with Java Programmazione Base
Object Oriented with Java Programmazione BaseObject Oriented with Java Programmazione Base
Object Oriented with Java Programmazione Base
 
OOP with C#
OOP with C#OOP with C#
OOP with C#
 

Similar to What's new in C# 7

Scala Programming Linux Day 2009
Scala Programming Linux Day 2009Scala Programming Linux Day 2009
Scala Programming Linux Day 2009
Massimiliano Dessì
 
Java OCA teoria 1
Java OCA teoria 1Java OCA teoria 1
Java OCA teoria 1
Valerio Radice
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript Overview
Francesco Sciuti
 
Capitolo 2 elementi di programmazione in vba
Capitolo 2   elementi di programmazione in vbaCapitolo 2   elementi di programmazione in vba
Capitolo 2 elementi di programmazione in vbaGiovanni Della Lunga
 
Py a6 python-database
Py a6 python-databasePy a6 python-database
Py a6 python-databaseMajong DevJfu
 
Vb.Net
Vb.NetVb.Net
Eclipse emf
Eclipse emfEclipse emf
Eclipse emf
Advenias
 
Office & VBA - Giorno 6
Office & VBA - Giorno 6Office & VBA - Giorno 6
Office & VBA - Giorno 6
Diego La Monica
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)STELITANO
 
Dal c a Java (3/3)
Dal c a Java (3/3)Dal c a Java (3/3)
Dal c a Java (3/3)
Marcello Missiroli
 
Programmazione e gestione della sicurezza: Verbale elettronico
Programmazione e gestione della sicurezza: Verbale elettronicoProgrammazione e gestione della sicurezza: Verbale elettronico
Programmazione e gestione della sicurezza: Verbale elettronico
Davide Ciambelli
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
Luciano Colosio
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.js
Michele Capra
 
Scala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perchéScala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perché
Edmondo Porcu
 
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
From The Front
 
What's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - FirenzeWhat's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - Firenze
Alberto Paro
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
K-Tech Formazione
 

Similar to What's new in C# 7 (20)

Scala Programming Linux Day 2009
Scala Programming Linux Day 2009Scala Programming Linux Day 2009
Scala Programming Linux Day 2009
 
Programming iOS lezione 3
Programming iOS lezione 3Programming iOS lezione 3
Programming iOS lezione 3
 
Java OCA teoria 1
Java OCA teoria 1Java OCA teoria 1
Java OCA teoria 1
 
Corso Java
Corso JavaCorso Java
Corso Java
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript Overview
 
Capitolo 2 elementi di programmazione in vba
Capitolo 2   elementi di programmazione in vbaCapitolo 2   elementi di programmazione in vba
Capitolo 2 elementi di programmazione in vba
 
Py a6 python-database
Py a6 python-databasePy a6 python-database
Py a6 python-database
 
Pycon
PyconPycon
Pycon
 
Vb.Net
Vb.NetVb.Net
Vb.Net
 
Eclipse emf
Eclipse emfEclipse emf
Eclipse emf
 
Office & VBA - Giorno 6
Office & VBA - Giorno 6Office & VBA - Giorno 6
Office & VBA - Giorno 6
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)
 
Dal c a Java (3/3)
Dal c a Java (3/3)Dal c a Java (3/3)
Dal c a Java (3/3)
 
Programmazione e gestione della sicurezza: Verbale elettronico
Programmazione e gestione della sicurezza: Verbale elettronicoProgrammazione e gestione della sicurezza: Verbale elettronico
Programmazione e gestione della sicurezza: Verbale elettronico
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.js
 
Scala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perchéScala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perché
 
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
Diversamente Javascript: si.. può.. fare! (di Mirko Ravaioli)
 
What's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - FirenzeWhat's Big Data? - Big Data Tech - 2015 - Firenze
What's Big Data? - Big Data Tech - 2015 - Firenze
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 

More from Marco Parenzan

Azure IoT Central per lo SCADA engineer
Azure IoT Central per lo SCADA engineerAzure IoT Central per lo SCADA engineer
Azure IoT Central per lo SCADA engineer
Marco Parenzan
 
Azure Hybrid @ Home
Azure Hybrid @ HomeAzure Hybrid @ Home
Azure Hybrid @ Home
Marco Parenzan
 
Static abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptx
Static abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptxStatic abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptx
Static abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptx
Marco Parenzan
 
Azure Synapse Analytics for your IoT Solutions
Azure Synapse Analytics for your IoT SolutionsAzure Synapse Analytics for your IoT Solutions
Azure Synapse Analytics for your IoT Solutions
Marco Parenzan
 
Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central
Marco Parenzan
 
Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT CentralPower BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central
Marco Parenzan
 
Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT CentralPower BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central
Marco Parenzan
 
Developing Actors in Azure with .net
Developing Actors in Azure with .netDeveloping Actors in Azure with .net
Developing Actors in Azure with .net
Marco Parenzan
 
Math with .NET for you and Azure
Math with .NET for you and AzureMath with .NET for you and Azure
Math with .NET for you and Azure
Marco Parenzan
 
Power BI data flow and Azure IoT Central
Power BI data flow and Azure IoT CentralPower BI data flow and Azure IoT Central
Power BI data flow and Azure IoT Central
Marco Parenzan
 
.net for fun: write a Christmas videogame
.net for fun: write a Christmas videogame.net for fun: write a Christmas videogame
.net for fun: write a Christmas videogame
Marco Parenzan
 
Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...
Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...
Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...
Marco Parenzan
 
Anomaly Detection with Azure and .NET
Anomaly Detection with Azure and .NETAnomaly Detection with Azure and .NET
Anomaly Detection with Azure and .NET
Marco Parenzan
 
Deploy Microsoft Azure Data Solutions
Deploy Microsoft Azure Data SolutionsDeploy Microsoft Azure Data Solutions
Deploy Microsoft Azure Data Solutions
Marco Parenzan
 
Deep Dive Time Series Anomaly Detection in Azure with dotnet
Deep Dive Time Series Anomaly Detection in Azure with dotnetDeep Dive Time Series Anomaly Detection in Azure with dotnet
Deep Dive Time Series Anomaly Detection in Azure with dotnet
Marco Parenzan
 
Azure IoT Central
Azure IoT CentralAzure IoT Central
Azure IoT Central
Marco Parenzan
 
Anomaly Detection with Azure and .net
Anomaly Detection with Azure and .netAnomaly Detection with Azure and .net
Anomaly Detection with Azure and .net
Marco Parenzan
 
Code Generation for Azure with .net
Code Generation for Azure with .netCode Generation for Azure with .net
Code Generation for Azure with .net
Marco Parenzan
 
Running Kafka and Spark on Raspberry PI with Azure and some .net magic
Running Kafka and Spark on Raspberry PI with Azure and some .net magicRunning Kafka and Spark on Raspberry PI with Azure and some .net magic
Running Kafka and Spark on Raspberry PI with Azure and some .net magic
Marco Parenzan
 
Time Series Anomaly Detection with Azure and .NETT
Time Series Anomaly Detection with Azure and .NETTTime Series Anomaly Detection with Azure and .NETT
Time Series Anomaly Detection with Azure and .NETT
Marco Parenzan
 

More from Marco Parenzan (20)

Azure IoT Central per lo SCADA engineer
Azure IoT Central per lo SCADA engineerAzure IoT Central per lo SCADA engineer
Azure IoT Central per lo SCADA engineer
 
Azure Hybrid @ Home
Azure Hybrid @ HomeAzure Hybrid @ Home
Azure Hybrid @ Home
 
Static abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptx
Static abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptxStatic abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptx
Static abstract members nelle interfacce di C# 11 e dintorni di .NET 7.pptx
 
Azure Synapse Analytics for your IoT Solutions
Azure Synapse Analytics for your IoT SolutionsAzure Synapse Analytics for your IoT Solutions
Azure Synapse Analytics for your IoT Solutions
 
Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central
 
Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT CentralPower BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central
 
Power BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT CentralPower BI Streaming Data Flow e Azure IoT Central
Power BI Streaming Data Flow e Azure IoT Central
 
Developing Actors in Azure with .net
Developing Actors in Azure with .netDeveloping Actors in Azure with .net
Developing Actors in Azure with .net
 
Math with .NET for you and Azure
Math with .NET for you and AzureMath with .NET for you and Azure
Math with .NET for you and Azure
 
Power BI data flow and Azure IoT Central
Power BI data flow and Azure IoT CentralPower BI data flow and Azure IoT Central
Power BI data flow and Azure IoT Central
 
.net for fun: write a Christmas videogame
.net for fun: write a Christmas videogame.net for fun: write a Christmas videogame
.net for fun: write a Christmas videogame
 
Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...
Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...
Building IoT infrastructure on edge with .net, Raspberry PI and ESP32 to conn...
 
Anomaly Detection with Azure and .NET
Anomaly Detection with Azure and .NETAnomaly Detection with Azure and .NET
Anomaly Detection with Azure and .NET
 
Deploy Microsoft Azure Data Solutions
Deploy Microsoft Azure Data SolutionsDeploy Microsoft Azure Data Solutions
Deploy Microsoft Azure Data Solutions
 
Deep Dive Time Series Anomaly Detection in Azure with dotnet
Deep Dive Time Series Anomaly Detection in Azure with dotnetDeep Dive Time Series Anomaly Detection in Azure with dotnet
Deep Dive Time Series Anomaly Detection in Azure with dotnet
 
Azure IoT Central
Azure IoT CentralAzure IoT Central
Azure IoT Central
 
Anomaly Detection with Azure and .net
Anomaly Detection with Azure and .netAnomaly Detection with Azure and .net
Anomaly Detection with Azure and .net
 
Code Generation for Azure with .net
Code Generation for Azure with .netCode Generation for Azure with .net
Code Generation for Azure with .net
 
Running Kafka and Spark on Raspberry PI with Azure and some .net magic
Running Kafka and Spark on Raspberry PI with Azure and some .net magicRunning Kafka and Spark on Raspberry PI with Azure and some .net magic
Running Kafka and Spark on Raspberry PI with Azure and some .net magic
 
Time Series Anomaly Detection with Azure and .NETT
Time Series Anomaly Detection with Azure and .NETTTime Series Anomaly Detection with Azure and .NETT
Time Series Anomaly Detection with Azure and .NETT
 

What's new in C# 7

  • 1. saturday 2017 WHAT’S NEW IN C# 7.X Marco Parenzan
  • 2. @MARCO_PARENZAN .NET, JavaScript,Azure ad IoT Developer, Trainer and Consultant Microsoft MVP 2017 for Azure Book Author @ Packt, LSWR Community Lead per 1nn0va
  • 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.
  • 4. C# 7.0 THE DATA RELEASE
  • 5. C# 7 OBJECTIVES Working with data  Pattern Matching  Tuples  Deconstruction  Discards Code Simplification  Expression Bodied Properties, Constructor Finalizer  Throw expression  Out Variables  Binary Literals and Digit separator Improved Performances  Local Functions  Return values and local variables by reference
  • 6. C# DESIGN  github.com/dotnet/csharplang (definition)  https://github.com/dotnet/roslyn (implementation)  https://github.com/dotnet/cli
  • 7. C# 7.2 https://github.com/dotnet/csharplang/tree/master/proposals/csharp-7.2 REF READONLY CONDITIONAL REF NON-TRAILING NAMED ARGUMENTS PRIVATE PROTECTED LEADING DIGIT SEPARATOR SPAN SAFETY
  • 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); }
  • 12. EXPRESSION-BODIED MEMBERS C # 6 expression-bodied members expanded Constructors Finalizers Indexers
  • 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);
  • 16. INFER TUPLE ELEMENT var z = (x,y); var xx = z.Item1; // 7.0 var xx = z.x; // 7.1+
  • 17. DISCARDS if (int.TryParse("4", out _)) {} _ = stats(null);
  • 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);
  • 27. saturday 2017 Marco Parenzan marco [dot] parenzan [at] 1nn0va [dot] it @marco_parenzan
  • 28. C# 1.0 – THE “MANAGED” RELEASE
  • 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
  • 44. C# 2.0 – THE “OBJECT MODEL” RELEASE
  • 45. C# 2.0 – THE “OBJECT MODEL” RELEASE Generics Partial types Anonymous methods Iterators Nullable types Getter/Setter separate accessibility Static classes
  • 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
  • 49. GENERIC COLLECTIONS AND INTERFACES System.Collections.Generic classes  List<ItemType>  Dictionary<K,V>  Stack<ItemType>  Queue<ItemType> System.Collections.Generic interfaces  IList<ItemType>  IDictionary<K,V>  ICollection<ItemType>  IEnumerable<ItemType>  IEnumerator<ItemType>  IComparable<OperandType>  IComparer<OperandType> 22/10/2017 MARCO PARENZAN 49
  • 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]; } } }
  • 56. C# 3.0 – THE “FUNCTIONAL” RELEASE
  • 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 VBOption 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
  • 62. XML LITERALS VB only!  Uno dei tanti divertissements…. 22/10/2017 MARCO PARENZAN 62
  • 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
  • 74. C# 4.0 – THE “INTEROPERABILITY” RELEASE
  • 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 MetodologicaMolti 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
  • 86. C# 5.0 – THE “ASYNCHRONOUS” RELEASE
  • 87. C# 5.0 – THE “ASYNCHRONOUS” RELEASE Asynchronous methods Caller info attributes
  • 88. C# 6.0 THE “DECLARATIVE” RELEASE
  • 89. C# 6.0 THE “DECLARATIVE” RELEASE Auto-property initializers Using Static Directive Dictionary Initializer Await in catch/finally Exception filters Exception filters Expression-bodied members Null propagation String interpolation nameof operator
  • 90. THE NAMEOF() OPERATOR Sometimes we want the name of an identifier as a string
  • 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.
  • 96. AUTO-PROPERTY INITIALIZATION (CONT) We can now do this! Reduces several lines of boiler-plating.
  • 97. AUTO-PROPERTY INITIALIZATION (CONT) In addition, you can use it even if the property has no setter (i.e. a truly read-only property):
  • 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:
  • 109. METHOD AND PROPERTY EXPRESSIONS Sometimes, we have properties or methods that are so simple, the body is mostly boilerplate
  • 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.
  • 114. STRING INTERPOLATION (CONT) So now, our example becomes: In addition, all string formatting options are available:
  • 115. ENHANCED EXCEPTION FILTERING .NET has long had exception filtering:
  • 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.
  • 117. ENHANCED EXCEPTION FILTERING (CONT) Let’s assume our exception looks like this:
  • 118. ENHANCED EXCEPTION FILTERING (CONT) To catch only retryable exceptions, we used to do this:
  • 119. ENHANCED EXCEPTION FILTERING (CONT) Now, with C# 6, you can specify a logical filter as well:
  • 120. ENHANCED EXCEPTION FILTERING (CONT) Now, you can have multiple catches on same type:
  • 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.
  • 126. NULL CONDITIONAL OPERATOR (CONT) The null conditional operator is not just for properties, you can use it for method calls as well.
  • 127. NULL CONDITIONAL OPERATOR (CONT) Also simplifies raising events:
  • 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 (?[…]):
  • 129. C# 6.0 THE “COMPILER REWRITE” RELEASE
  • 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
  • 133. WHAT IS "ROSLYN"? Each phase now has corresponding API
  • 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….