#13: L’inizializzatore agisce direttamente sul backing field. Non usa il set della proprietà.
Gli inizializzatori sono eseguiti nell’ordine di apparizione
Non possono usare this, dato che vengono eseguiti prima che l’oggetto sia stato inizializzato.
Con I costruttori primari potrebbero essere inizializzati con i parametri dei costruttori stessi
#14: Le proprietà automatiche possono ora anche avere il solo get
Implementate con backing field readonly
2) E quindi possono essere inizializzate anche nel costruttore
#16: Gli exception filters sono particolarmente indicate per il catche rethrow perchè lascia lo stack invariato
Una pratica commune di abuso accettato è quella di usare I filtri per il logging delle eccezioni, senza catturarla.
Basta chiamare un metodo che fa il log e restituisce false.
#17: Object e collection initializer introdotti con C# 3 forniscono una sintassi per inizializzare campi e proprietà di un oggetto, o per riempire collezioni con un insieme iniziale di elementi.
L’inizializzazione di dizionari o di altri oggetti con indicizzatori è meno elegante (per qualcuno), quindi è stata aggiunta una sintassi per assegnare dei valor alle chiavi
Usando un indicizzatore qualunque della classe.
L’esempio numbers mostra che la differenza non è poi così ampia.
Ma provando con una classe custom con indicizzatore
#18: Ma provando con una classe custom con indicizzatore
public class Person
{
public string Name { get; set; }
public Person(string name)
{
Name = name;
}
public string[] numbers = new string[5];
public string this[int index]
{
get
{
return numbers[index];
}
set
{
numbers[index] = value;
}
}
}
#19: Spesso il codice diventa pieno di check per evitare null reference exception
L’operatore null propagating, o null conditional consente di accedere ad un membro solo se l’oggetto è non null
Inoltre può essere usato con membri come indicizzatori, e come dice il nome propagation, in maniera concatenata. Con comportamento di corto circuito, appa trova un membro null, restituisce null
string str = null;
int? len = str?.Length;
char? primo = str?[0];
Console.WriteLine(len);
Console.WriteLine(primo);
Person p = null;
string city = p?.MyAddress?.City?.ToLower();
public class Person {
public Address MyAddress { get; set; }
}
public class Address {
public string City { get; set; }
}
#20: In c# 5.0 non era possibile, costringendoci a workaround come variabili booleane o altre amenità, tutto ciò perché ci è stato detto che era impossibile implementare tale feature.
In C#6, è possibile, quindi, evidentemente, non era così impossibile. O perlomeno, hanno capito come farlo: sicuramente non è stato semplice, e non ci interessa sapere come funziona: questo è il vantaggio di avere funzionalità asincrone supportate nativamente dal linguaggio.
#21: Metodi, proprietà, operatori possono essere implementati utilizzando come loro corpo un’espressione labda
#22: Certe volte è necessario stampare o ricavare una stringa che rappresenta il nome di alcuno elementi del programma,
Per esempio per passare ad
ArgumentException il nome dell’argomento colpevole
Oppure generando un evento PropertyChanged per indicare il nome della prop
Il tutto è naturalmnente fattibile con le stringhe, ma oltre a essere soggetto a errore di battitura, non va d’accordo con esigenze di refactoring
L’operatore nameod
(if x == null) throw new ArgumentNullException(nameof(x));
Si possono usare come operandi anche nomi di membri con sintassi dotted, l’operatore restituisce l’ultimo
WriteLine(nameof(Person.Address.ZipCode)); // prints "ZipCode"
Non è come reflection, perchè il compilatore sostituisce direttamente il nome con una stringa