Progetti ed Esercizi in C#
Metti in pratica le tue conoscenze con progetti realistici e sfide di programmazione
🎯 Impara Facendo
La programmazione si impara facendo. Questa lezione contiene progetti ed esercizi
pratici che ti permetteranno di applicare tutti i concetti appresi durante il corso. Ogni progetto
è pensato per rafforzare competenze specifiche e prepararti a situazioni reali di sviluppo.
💡 Come Affrontare i Progetti
Non avere fretta di guardare le soluzioni! Prova prima a implementare il codice da solo,
anche se ci metti più tempo. Gli errori che farai e risolverai saranno le tue
migliori lezioni. Usa le soluzioni solo come riferimento finale.
📱 Mini-Progetto: Sistema di Gestione Rubrica
Questo progetto ti permetterà di applicare molti dei concetti visti nel corso. Implementa una
rubrica telefonica completa con gestione di contatti, ricerca avanzata e persistenza dei dati.
📝 Aggiunta di Contatti
- Nome, cognome, numeri di telefono (multipli)
- Email (con validazione del formato)
- Indirizzo
- Note aggiuntive
🔍 Ricerca di Contatti
- Ricerca per nome/cognome
- Ricerca per numero di telefono
- Ricerca per email
- Visualizzazione dei risultati
✏️ Modifica e Eliminazione
- Aggiornamento di informazioni esistenti
- Rimozione di contatti
- Backup dei contatti eliminati (cestino)
💾 Persistenza dei Dati
- Salvataggio dei contatti su file CSV
- Caricamento dei contatti da file
- Backup automatico
- Crea una classe Contatto con tutte le proprietà necessarie
- Implementa una classe Rubrica che gestisce una collezione di contatti
- Crea una classe RubricaFileManager per gestire il salvataggio/caricamento
- Implementa una classe RubricaUI che gestisce l’interazione con l’utente
- Utilizza LINQ per implementare le funzionalità di ricerca
- Implementa la gestione delle eccezioni per rendere l’applicazione robusta
💻 Implementazione Completa
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
// Classe per rappresentare un contatto
public class Contatto
{
public string Nome { get; set; }
public string Cognome { get; set; }
public List Telefoni { get; set; } = new List();
public string Email { get; set; }
public string Indirizzo { get; set; }
public string Note { get; set; }
public override string ToString()
{
return $"{Nome} {Cognome} - Tel: {string.Join(", ", Telefoni)} - Email: {Email}";
}
}
// Classe per gestire la rubrica
public class Rubrica
{
private List contatti = new List();
private List cestino = new List();
public void AggiungiContatto(Contatto contatto)
{
contatti.Add(contatto);
}
public bool RimuoviContatto(string nome, string cognome)
{
var contatto = contatti.FirstOrDefault(c =>
c.Nome.Equals(nome, StringComparison.OrdinalIgnoreCase) &&
c.Cognome.Equals(cognome, StringComparison.OrdinalIgnoreCase));
if (contatto != null)
{
contatti.Remove(contatto);
cestino.Add(contatto); // Backup nel cestino
return true;
}
return false;
}
// Ricerca utilizzando LINQ
public IEnumerable CercaPerNome(string nome)
{
return contatti.Where(c =>
c.Nome.Contains(nome, StringComparison.OrdinalIgnoreCase) ||
c.Cognome.Contains(nome, StringComparison.OrdinalIgnoreCase));
}
public IEnumerable CercaPerTelefono(string telefono)
{
return contatti.Where(c =>
c.Telefoni.Any(t => t.Contains(telefono)));
}
public IEnumerable CercaPerEmail(string email)
{
return contatti.Where(c =>
c.Email.Contains(email, StringComparison.OrdinalIgnoreCase));
}
public IEnumerable TuttiContatti()
{
return contatti.OrderBy(c => c.Cognome).ThenBy(c => c.Nome);
}
public IEnumerable Cestino()
{
return cestino;
}
}
// Classe per gestire il salvataggio su file
public class RubricaFileManager
{
public void SalvaSuFile(Rubrica rubrica, string percorso)
{
try
{
using (StreamWriter sw = new StreamWriter(percorso))
{
foreach (var contatto in rubrica.TuttiContatti())
{
sw.WriteLine($"{contatto.Nome};{contatto.Cognome};" +
$"{string.Join(",", contatto.Telefoni)};" +
$"{contatto.Email};{contatto.Indirizzo};{contatto.Note}");
}
}
Console.WriteLine("✅ Dati salvati correttamente");
}
catch (Exception ex)
{
Console.WriteLine($"❌ Errore nel salvataggio: {ex.Message}");
}
}
public Rubrica CaricaDaFile(string percorso)
{
Rubrica rubrica = new Rubrica();
if (!File.Exists(percorso))
{
Console.WriteLine("📁 Nessun file trovato, rubrica vuota");
return rubrica;
}
try
{
foreach (string linea in File.ReadAllLines(percorso))
{
var parti = linea.Split(';');
if (parti.Length >= 4)
{
var contatto = new Contatto
{
Nome = parti[0],
Cognome = parti[1],
Telefoni = parti[2].Split(',').ToList(),
Email = parti[3],
Indirizzo = parti.Length > 4 ? parti[4] : "",
Note = parti.Length > 5 ? parti[5] : ""
};
rubrica.AggiungiContatto(contatto);
}
}
Console.WriteLine("✅ Dati caricati correttamente");
}
catch (Exception ex)
{
Console.WriteLine($"❌ Errore nel caricamento: {ex.Message}");
}
return rubrica;
}
}
// Classe per l'interfaccia utente
public class RubricaUI
{
private Rubrica rubrica;
private RubricaFileManager fileManager = new RubricaFileManager();
private string filePath = "rubrica.csv";
public RubricaUI()
{
rubrica = fileManager.CaricaDaFile(filePath);
}
public void Avvia()
{
bool continua = true;
while (continua)
{
Console.WriteLine("\n╔═══════════════════════════════╗");
Console.WriteLine("║ RUBRICA TELEFONICA ║");
Console.WriteLine("╚═══════════════════════════════╝");
Console.WriteLine("1. 📝 Aggiungi contatto");
Console.WriteLine("2. 🔍 Cerca contatto");
Console.WriteLine("3. 📋 Visualizza tutti i contatti");
Console.WriteLine("4. ❌ Rimuovi contatto");
Console.WriteLine("5. 💾 Salva ed esci");
Console.Write("\nScegli un'opzione: ");
string scelta = Console.ReadLine();
switch (scelta)
{
case "1":
AggiungiContatto();
break;
case "2":
CercaContatto();
break;
case "3":
VisualizzaContatti();
break;
case "4":
RimuoviContatto();
break;
case "5":
fileManager.SalvaSuFile(rubrica, filePath);
continua = false;
Console.WriteLine("👋 Arrivederci!");
break;
default:
Console.WriteLine("❌ Opzione non valida");
break;
}
}
}
private void AggiungiContatto()
{
Console.WriteLine("\n📝 AGGIUNGI CONTATTO");
var contatto = new Contatto();
Console.Write("Nome: ");
contatto.Nome = Console.ReadLine();
Console.Write("Cognome: ");
contatto.Cognome = Console.ReadLine();
Console.WriteLine("Inserisci numeri di telefono (invio per terminare):");
string telefono;
do
{
Console.Write("Telefono: ");
telefono = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(telefono))
{
contatto.Telefoni.Add(telefono);
}
} while (!string.IsNullOrWhiteSpace(telefono));
Console.Write("Email: ");
contatto.Email = Console.ReadLine();
Console.Write("Indirizzo: ");
contatto.Indirizzo = Console.ReadLine();
Console.Write("Note: ");
contatto.Note = Console.ReadLine();
rubrica.AggiungiContatto(contatto);
Console.WriteLine("✅ Contatto aggiunto con successo!");
}
private void CercaContatto()
{
Console.WriteLine("\n🔍 CERCA CONTATTO");
Console.WriteLine("1. Per nome/cognome");
Console.WriteLine("2. Per telefono");
Console.WriteLine("3. Per email");
Console.Write("Scegli un'opzione: ");
string scelta = Console.ReadLine();
IEnumerable risultati = null;
switch (scelta)
{
case "1":
Console.Write("Inserisci nome o cognome: ");
string nome = Console.ReadLine();
risultati = rubrica.CercaPerNome(nome);
break;
case "2":
Console.Write("Inserisci numero di telefono: ");
string telefono = Console.ReadLine();
risultati = rubrica.CercaPerTelefono(telefono);
break;
case "3":
Console.Write("Inserisci email: ");
string email = Console.ReadLine();
risultati = rubrica.CercaPerEmail(email);
break;
default:
Console.WriteLine("❌ Opzione non valida");
return;
}
Console.WriteLine("\n📊 RISULTATI DELLA RICERCA:");
int count = 0;
foreach (var contatto in risultati)
{
Console.WriteLine($"• {contatto}");
count++;
}
Console.WriteLine($"\n✅ Trovati {count} contatti");
}
private void VisualizzaContatti()
{
Console.WriteLine("\n📋 ELENCO CONTATTI:");
int count = 0;
foreach (var contatto in rubrica.TuttiContatti())
{
Console.WriteLine($"{count + 1}. {contatto}");
count++;
}
Console.WriteLine($"\n📊 Totale: {count} contatti");
}
private void RimuoviContatto()
{
Console.WriteLine("\n❌ RIMUOVI CONTATTO");
Console.Write("Nome: ");
string nome = Console.ReadLine();
Console.Write("Cognome: ");
string cognome = Console.ReadLine();
if (rubrica.RimuoviContatto(nome, cognome))
{
Console.WriteLine("✅ Contatto rimosso con successo");
}
else
{
Console.WriteLine("❌ Contatto non trovato");
}
}
}
// Programma principale
class Program
{
static void Main()
{
RubricaUI ui = new RubricaUI();
ui.Avvia();
}
}
- OOP: Classi, proprietà, incapsulamento
- Collections: List<T> per gestire contatti
- LINQ: Where, FirstOrDefault, OrderBy per ricerche
- File I/O: StreamWriter, File.ReadAllLines
- Exception Handling: try-catch per gestire errori
- String Manipulation: Split, Join, Contains
💪 Esercizi per Consolidare le Conoscenze
📝 Esercizio 1: Calcolatrice Avanzata
Crea una calcolatrice che supporti operazioni avanzate e gestione della memoria.
- Operazioni di base (+, -, *, /)
- Potenza (x^y)
- Radice quadrata
- Logaritmo naturale
- Memoria per salvare/recuperare valori (M+, M-, MR, MC)
- Storico delle operazioni
Implementa un’interfaccia IOperazione che rappresenta un’operazione
matematica con un metodo Esegui(double a, double b). Poi crea classi
concrete per ogni operazione (Addizione, Sottrazione, ecc.) che implementano questa interfaccia.
📝 Esercizio 2: Sistema di Prenotazione Cinema
Implementa un sistema completo per gestire le prenotazioni di un cinema multi-sala.
- Gestione di più sale con posti numerati
- Prenotazione e cancellazione posti
- Visualizzazione della mappa dei posti (disponibili/occupati)
- Diversi tipi di biglietto (intero, ridotto, bambini)
- Calcolo dell’incasso totale per sala/film
- Salvataggio dello stato su file
Usa una matrice bidimensionale (array 2D) per rappresentare i posti in una sala.
Ad esempio: bool[,] posti = new bool[10, 15]; per una sala con 10 file e 15 posti per fila.
true = occupato, false = libero.
📝 Esercizio 3: Gestione Biblioteca (Estensione)
Estendi il progetto della biblioteca visto nella lezione OOP aggiungendo funzionalità avanzate.
- Gestione di più copie dello stesso libro
- Ricerca avanzata per genere, autore, anno
- Storico completo dei prestiti con date
- Sistema utenti con registrazione e autenticazione
- Scadenza prestiti (es. 14 giorni) e multe per ritardi
- Sistema di prenotazioni per libri non disponibili
Usa DateTime per gestire le date di prestito e scadenza.
Calcola la differenza con DateTime.Now - dataPrestito per ottenere un
TimeSpan e verificare i giorni di ritardo.
🚀 Progetti Avanzati
Questi progetti sono più complessi e richiedono l’integrazione di molti concetti.
Sono ideali per creare un portfolio o per approfondire la tua preparazione.
🏪 Progetto 1: Sistema di Gestione Inventario
Crea un sistema completo per gestire l’inventario di un negozio con funzionalità professionali.
Funzionalità Core:
- Categorie e sottocategorie di prodotti (struttura gerarchica)
- Gestione magazzino con quantità minime e allarmi per scorte basse
- Movimenti di carico e scarico con registro cronologico
- Ricerca e filtri avanzati (per categoria, prezzo, disponibilità)
- Report e statistiche (prodotti più venduti, valore inventario)
- Sistema di fornitori e ordini
Funzionalità Avanzate (Opzionali):
- Interfaccia grafica con WPF o Windows Forms
- Export dati in CSV o Excel
- Codici a barre per prodotti
- Multi-magazzino
🎮 Progetto 2: Gioco Quiz a Domande
Sviluppa un gioco quiz interattivo con sistema di punteggio e classifiche.
Funzionalità Core:
- Database di domande organizzate per categoria (Storia, Scienza, Sport, ecc.)
- Sistema di punteggio con livelli di difficoltà (facile, medio, difficile)
- Timer per rispondere (es. 30 secondi per domanda)
- Classifica dei migliori giocatori (Top 10)
- Editor per aggiungere nuove domande
- Modalità partita rapida o campionato
Funzionalità Avanzate (Opzionali):
- Modalità multiplayer (a turni sullo stesso PC)
- Sistema di aiuti (50:50, chiedi all’amico, ecc.)
- Statistiche per giocatore
- Suoni ed effetti visivi
💰 Progetto 3: Gestione Finanze Personali
Applicazione per tracciare entrate, uscite e gestire il budget personale.
Funzionalità Core:
- Registrazione di entrate e uscite con categoria e data
- Categorie personalizzabili (Spesa, Trasporti, Svago, ecc.)
- Budget mensili per categoria con avvisi di superamento
- Visualizzazione bilancio corrente
- Report mensili e annuali
- Grafici di spesa per categoria
Funzionalità Avanzate (Opzionali):
- Gestione di più conti (contanti, carta, conto corrente)
- Transazioni ricorrenti (stipendio, affitto, abbonamenti)
- Export/Import dati
- Previsioni di spesa basate sullo storico
- Inizia semplice: Implementa prima le funzionalità core, poi aggiungi quelle avanzate
- Usa Git: Versionare il codice ti aiuterà a sperimentare senza paura
- Pianifica: Disegna diagrammi delle classi prima di iniziare a codificare
- Testa frequentemente: Non aspettare di finire tutto per testare il codice
- Documenta: Scrivi commenti e README per spiegare il tuo lavoro
📚 Risorse per Continuare ad Apprendere
📖 Documentazione Ufficiale
🎓 Corsi Online
- Pluralsight – Corsi professionali C# e .NET
- Udemy – Vasta selezione di corsi in italiano e inglese
- Coursera – Corsi universitari
- Codecademy – Corso interattivo C#
📚 Libri Consigliati
- “C# 12 and .NET 8 – Modern Cross-Platform Development” di Mark J. Price
- “C# in Depth” di Jon Skeet (4a edizione)
- “Head First C#” di Andrew Stellman e Jennifer Greene
- “Pro C# 10 with .NET 6” di Andrew Troelsen e Philip Japikse
- “Clean Code” di Robert C. Martin (principi generali)
👥 Community e Forum
- Stack Overflow (tag C#) – Per domande tecniche
- r/csharp – Subreddit dedicato a C#
- Discord C# – Community in tempo reale
- GitHub – Esplora progetti open source
🛠️ Strumenti Consigliati
- Visual Studio 2022 Community – IDE completo e gratuito
- Visual Studio Code – Editor leggero con estensioni C#
- JetBrains Rider – IDE alternativo (a pagamento)
- LINQPad – Per sperimentare con LINQ
- Git – Controllo versione (essenziale)
Ora che hai completato questo corso, il modo migliore per progredire è costruire progetti reali.
Scegli un progetto che ti appassiona e inizia a svilupparlo. Non preoccuparti di fare errori –
sono parte del processo di apprendimento. Buona programmazione! 🚀
- Sintassi e fondamenti C#
- Programmazione orientata agli oggetti
- Gestione dati e collezioni
- File I/O e persistenza
- Best practices e pattern
- Completa i progetti proposti
- Contribuisci a progetti open source
- Approfondisci ASP.NET, WPF, Xamarin
- Partecipa alle community
- Non smettere mai di imparare!
Lezione 14 del Corso C# Completo – Lezione Finale
Grazie per aver seguito questo corso. Continua a programmare e a imparare! 🚀