Basi
Hello World
Console.WriteLine("Hello, World!"); // top-level (C# 10+) // Classico: class Program { static void Main() { ... } }
Build ed Esecuzione
dotnet new console -n MyApp # crea progetto dotnet run # compila ed esegui dotnet build # solo compilazione
Variabili e Costanti
int x = 42; var name = "Alice"; // inferenza di tipo const double Pi = 3.14159; readonly int maxRetries = 3; // impostato una volta, nel costruttore
Tipi
Tipi Valore
intIntero con segno a 32 bit
longIntero con segno a 64 bit
floatVirgola mobile a 32 bit (suffisso f)
doubleVirgola mobile a 64 bit
decimalAlta precisione 128 bit (suffisso m)
booltrue / false
charCarattere Unicode a 16 bit
Tipi Riferimento
stringTesto UTF-16 immutabile
objectTipo base per tutti i tipi
dynamicBypassa il controllo di tipo a compile-time
int[]Array di interi
List<T>Lista generica (System.Collections.Generic)
Nullable e Tuple
int? age = null; // tipo valore nullable string? name = null; // riferimento nullable (C# 8+) var point = (X: 1, Y: 2); // tupla nominata Console.WriteLine(point.X);
Funzionalità Stringa
string name = "World"; string msg = $"Hello, {name}!"; // interpolazione string path = @"C:\Users\file.txt"; // verbatim string raw = """raw "string" here"""; // raw (C# 11+)
Controllo del Flusso
If / Else
if (x > 0) Console.WriteLine("positivo"); else if (x == 0) Console.WriteLine("zero"); else Console.WriteLine("negativo");
Switch e Pattern Matching
string label = x switch { > 0 => "positivo", 0 => "zero", _ => "negativo" }; if (obj is string s && s.Length > 0) { } // pattern match
Cicli
for (int i = 0; i < 10; i++) { } foreach (var item in collection) { } while (condition) { } do { } while (condition);
Classi
Definizione di Classe
public class Person { public string Name { get; set; } public int Age { get; init; } // init-only (C# 9+) public Person(string name, int age) { Name = name; Age = age; } }
Record (C# 9+)
public record Point(double X, double Y); var p1 = new Point(1, 2); var p2 = p1 with { X = 3 }; // copia non distruttiva // auto: Equals, GetHashCode, ToString, deconstruct
Ereditarietà
public abstract class Shape { public abstract double Area(); } public class Circle(double r) : Shape { public override double Area() => Math.PI * r * r; }
Modificatori di Accesso
publicAccessibile da ovunque
privateSolo stessa classe (default per i membri)
protectedStessa classe e classi derivate
internalSolo stesso assembly (default per le classi)
protected internalStesso assembly o classi derivate
Interfacce
Definizione di Interfaccia
public interface IShape { double Area(); double Perimeter() => 0; // implementazione default (C# 8+) } public class Rect(double w, double h) : IShape { public double Area() => w * h; }
Interfacce Comuni
IEnumerable<T>Supporto iterazione (foreach, LINQ)
IDisposablePulizia deterministica (istruzione using)
IComparable<T>Ordinamento naturale per la classificazione
IEquatable<T>Confronto di uguaglianza per valore
ICloneableClonazione oggetti
LINQ
Sintassi a Metodo
var result = numbers .Where(n => n > 3) .OrderBy(n => n) .Select(n => n * 2) .ToList();
Sintassi a Query
var result = from n in numbers where n > 3 orderby n select n * 2;
Metodi LINQ Comuni
.Where(pred)Filtra gli elementi
.Select(func)Proietta/trasforma gli elementi
.OrderBy(key)Ordina in modo crescente
.GroupBy(key)Raggruppa gli elementi per chiave
.First() / .FirstOrDefault()Primo elemento (o default)
.Any(pred)true se qualsiasi elemento corrisponde
.Count()Numero di elementi
.Sum() / .Average()Aggregazione valori numerici
.Distinct()Rimuove i duplicati
.SelectMany(func)Appiattisce le collezioni annidate
Async/Await
Metodo Async
public async Task FetchAsync(string url) { using var client = new HttpClient(); return await client.GetStringAsync(url); }
Combinatori Task
var results = await Task.WhenAll(task1, task2, task3); var first = await Task.WhenAny(task1, task2);
Pattern Async
TaskRitorno async void (nessun risultato)
Task<T>Ritorno async con risultato di tipo T
ValueTask<T>Task leggero per percorsi sincroni veloci
await foreachIterazione async su IAsyncEnumerable
CancellationTokenCancellazione cooperativa per operazioni async
Collezioni
Collezioni Comuni
List<T>Array dinamico, accesso per indice veloce
Dictionary<K,V>Hash map, ricerca O(1) per chiave
HashSet<T>Elementi unici, ricerca O(1)
Queue<T>Collezione FIFO
Stack<T>Collezione LIFO
LinkedList<T>Lista doppiamente concatenata
SortedDictionary<K,V>Ordinato per chiave (basato su albero)
Utilizzo Dictionary
var dict = new Dictionary { ["Alice"] = 90, ["Bob"] = 85 }; dict.TryGetValue("Alice", out int score); foreach (var (key, val) in dict) { }
Collezioni Immutabili
using System.Collections.Immutable; var list = ImmutableList.Create(1, 2, 3); var newList = list.Add(4); // restituisce nuova lista
Proprietà
Sintassi delle Proprietà
public string Name { get; set; } public int Age { get; private set; } public string Email { get; init; } // init-only public string Display => $"{Name} ({Age})"; // calcolata
Indicizzatori
public double this[int row, int col] { get => data[row, col]; set => data[row, col] = value; }
Pattern Proprietà
{ get; set; }Auto-proprietà lettura-scrittura
{ get; }Sola lettura (impostabile solo nel costruttore)
{ get; init; }Sola lettura dopo inizializzazione (C# 9+)
{ get; private set; }Pubblicamente leggibile, privatamente scrivibile
=> expressionProprietà expression-bodied (calcolata)
Eccezioni
Try / Catch / Finally
try { int result = int.Parse(input); } catch (FormatException ex) { Console.Error.WriteLine(ex.Message); } catch (Exception ex) when (ex is not OutOfMemoryException) { } finally { /* eseguito sempre */ }
Istruzione Using
using var file = File.OpenRead("data.txt"); // file.Dispose() chiamato automaticamente allo scope end // equivalente a try/finally con Dispose()
Eccezioni Comuni
ArgumentNullExceptionArgomento null passato al metodo
ArgumentOutOfRangeExceptionArgomento fuori dall'intervallo valido
InvalidOperationExceptionOperazione non valida per lo stato corrente
NullReferenceExceptionDereferenziamento di oggetto null
KeyNotFoundExceptionChiave non trovata nel dizionario
NotImplementedExceptionMetodo non ancora implementato
Eccezione Personalizzata
public class AppException : Exception { public int Code { get; } public AppException(string msg, int code) : base(msg) { Code = code; } }