C SHARP 9
-
TOP LEVEL STATEMENT
Scriviamo il solito programma Console usando la riga di comando dotnet new console -o TopLevelStatement.
using System; /*--Cicliamo con un loop tutti gli argomenti passati dalla riga di comando all'array di stringhe args. Fatto ciò andiamo ad eliminare dal programma il namespace, la classe program e il metodo Main. L'utilità del top level statement la si può vedere a livello didattico.*/ foreach (var item in args) Console.WriteLine(item);
Il programma funziona ugualmente e non è successo nulla di magico, è il compilatore che ha creato dietro le quinte la classe Program, il metodo Main e il namespace.
-
INIT ONLY SETTERS
Questa nuova caratteristica del linguaggio ci permette di utilizzare proprietà di sola lettura ma che possono essere inizializzate.
using System; var instance = new Program() { MyProp="primo"; }; //instance.MyProp="secondo"; instance.Show(); class Program { /*--SE VOGLIAMO CHE MYPROP SIA IN SOLA LETTURA POSSIAMO ELIMINARE IL SET DALLA PROPRIETA'. TUTTAVIA A VOLTE C'E' L'ESIGENZA DI RENDERE UNA PROPRIETA' IN SOLA LETTURA MA INIZIALIZZATA AD UN VALORE. PER FARE CIO' BASTA AGGIUNGERE LA PAROLA CHIAVE INIT NEL SETTER. LA PROPRIETA' E' CHIAMATA IMMUTABILE IN QUANTO PUO' ESSERE INIZIALIZZATA SOLO UNA VOLTA.*/ public string MyProp {get;init;} public void Show() { Console.WriteLine($"MyProp = {MyProp}"); } }
-
RECORD
I Record sono un aggiunta importante per quanto riguarda il linguaggio C# in quanto si possono usare i reference types con una semantica tipica dei tipi valore in particolare per l’uguaglianza, inoltre i Record servono a creare entità immutabili.
DATA MODEL
Quando parliamo di Data Model lo facciamo riferendoci a un particolare Tipo a Data Type che noi introduciamo in un nostro programma. Normalmente viene implementato come una classe o una struttura. Un Data Model ha la particolarità di rappresentare informazioni costituite principalmente da dati senza funzionalità. Inoltre le istanze di un Data Model sono considerate immutabili, cioè una volta che abbiamo inizializzato tutte le proprietà, queste dovrebbero risultare immutabili per ottenere una solidità e una consistenza dei dati.
using System; Libro libro1 = new Libro("L'isola misteriosa","Jules Verne"); Libro libro2 = new Libro("L'isola misteriosa","Jules Verne"); //Libro libro2 = new Libro("Neuromante","William Gibson"); Console.WriteLine(libro1==libro2);//FALSE (TRUE con record) Console.WriteLine(libro1);//LIBRO /*--Dalla Console riceviamo False e Libro questo perché la comparazione di due reference types si basa sui riferimenti, quindi essendoci due diversi reference che puntano a libro1 e libro2 l'uguaglianza sarà false. Inoltre visualizzare nel terminale l'oggetto che è associato ad una variabile provoca l'esecuzione del metodo ToString() della classe Object. Dal punto di vista del Data Model abbiamo un problema, vorremmo che la comparazione di due oggetti aventi la medesima proprietà dia Vero e non Falso. Per avere un comportamento più vicino ad un data model sostituiamo la parola chiave Class con record. Un record è sempre un reference types ma con caratteristiche particolari. Innanzitutto il confronto per uguaglianza questa volta restituisce true come volevamo, questo perchè il record type ha usato una semantica a valore anzichè a riferimento e visto che le proprietà sono uguali il confronto ritorna True. Stampando a Console il valore di Libro1 questa volta il metodo ToString() torna Titolo e Autore di Libro1 */ record Libro { public string Titolo {get;init;} public string Autore {get;init;} public Libro() { } public Libro(string titolo, string autore) { Titolo=titolo; Autore=autore; } }
SINTASSI POSIZIONALE
Abbiamo scritto un record che rappresenta un ipotetico Data Model di un libro. Con la sintassi posizionale possiamo eliminare gran parte del codice e scrivere semplicemente:
record Libro(string Titolo, string Autore);
La parte iniziale della dichiarazione è rimasta intatta abbiamo usate la keyword record e il Tipo Libro, poi abbiamo introdotto tra parentesi le proprietà che vogliamo assegnare al nostro record. Ovviamente è il compilatore che dietro le quinte fa il lavoro per noi, in particolare:
Mandando in esecuzione questa riga di codice il risultato rimane immutato.
MODIFICA NON DISTRUTTIVA
using System; Libro libro1 = new Libro("L'isola misteriosa","Jules Verne"); Libro libro2 = libro1 with {Autore = "Giulio Verne"}; //libro1.Autore="Pippo"; //ERRORE /*--A volte può risultare utile modificare una proprietà, per fare ciò il C# ci mette a disposizione un metodo di duplicazione del record durante la quale le proprietà possono essere modificate. Per duplicare un record che ripetiamo è un reference types non basta l'operatore di assegnazione, ma per sdoppiare i reference e quindi modificarne le proprietà occorre usare l'operatore with. Una volta modificate le proprietà che occorre modificare libro2 è di nuovo un tipo immutabile.*/ Console.WriteLine(libro2.Autore); record Libro(string Titolo, string Autore);
EREDITARIETA’
using System; Libro libro1 = new Libro("L'isola misteriosa","Jules Verne"); LibroDigitale libro2 = new LibroDigitale("Neuromante","William Gibson","8 ore"); Console.WriteLine(libro1); Console.WriteLine(libro2); record Libro(string Titolo, string Autore); record LibroDigitale(string Titolo, string Autore, string Durata):Libro(Titolo,Autore);
-
NET INTERACTIVE NOTEBOOKS
È uno strumento di apprendimento, simile a quello di Phyton. Occorre installare l’estensione indicata in figura, l’ultima versione di visual studio code e .NET 5.0 ultima release.
Una volta installata l’estensione premere F1 e creare un nuovo notebook.
- TARGET-TYPED NEW
List<int> myInt = new List<int>();
In C#9 possiamo semplificare la sintassi.
List<int> myInt = new();
- NUOVE KEYWORD AND OR E NOT
if(Title is “MyTytle” or not ({Lenght:>=20 } And {Length:<=200}))
Throw(new ArgumentException(“Title is not valid”);
APPROFONDIMENTO
I record in C# 9.0 rappresentano una delle novità più interessanti introdotte nel linguaggio. Essi forniscono un modo conciso e dichiarativo per definire tipi di dati immutabili. Vediamo una descrizione dettagliata di come funzionano e come possono essere utilizzati:
Definizione di un Record
Un record in C# si definisce con la parola chiave record. Ecco un esempio di un record che rappresenta una persona:
public record Person(string FirstName, string LastName);
Caratteristiche Principali dei Record
1. Immutabilità:
• Le proprietà dei record sono generalmente immutabili per impostazione predefinita. Si può modificare questa impostazione usando i setter init.
2. Generazione Automatica di Metodi:
• C# genera automaticamente metodi come Equals, GetHashCode, e ToString per i record, basandosi sui valori delle proprietà.
• Esempio:
var person1 = new Person(“John”, “Doe“);
var person2 = new Person(“John”, “Doe“);
Console.WriteLine(person1 == person2); // Output: True
Console.WriteLine(person1); // Output: Person { FirstName = John, LastName = Doe }
3. Espressione with:
• Permette di creare una copia di un record con alcune modifiche:
var person1 = new Person(“John”, “Doe“);
var person2 = person1 with { LastName = “Smith” };
Console.WriteLine(person2); // Output: Person { FirstName = John, LastName = Smith }
5. Ereditarietà:
• I record possono partecipare all’ereditarietà come le classi.
public record Employee(string FirstName, string LastName, string Position) : Person(FirstName, LastName);
Uso Avanzato dei Record
Proprietà init-only
Le proprietà possono essere inizializzate solo durante la creazione dell’oggetto o mediante l’espressione with:
public record Car
{
public string Make { get; init; }
public string Model { get; init; }
}
Record Posizionali vs. Record con Membri
Oltre alla dichiarazione posizionale, i record possono essere definiti come classi con membri:
public record Book
{
public string Title { get; init; }
public string Author { get; init; }
public Book(string title, string author)
{
Title = title;
Author = author;
}
}
Esempio Completo
Ecco un esempio più completo che mostra diverse caratteristiche dei record:
public record Person(string FirstName, string LastName);
public record Student(string FirstName, string LastName, string School) : Person(FirstName, LastName);
public class Program
{
public static void Main()
{
var student1 = new Student(“John”, “Doe”, “High School“);
var student2 = student1 with { LastName = “Smith” };
Console.WriteLine(student1); // Output: Student { FirstName = John, LastName = Doe, School = High School }
Console.WriteLine(student2); // Output: Student { FirstName = John, LastName = Smith, School = High School }
Console.WriteLine(student1 == student2); // Output: False
}
}
Lascia un commento