Metti in pratica le tue conoscenze con progetti realistici e sfide di programmazione.
🖥️ In pratica con Windows Forms: Progetto finale: gestionale Biblioteca.
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.
🎯 Funzionalità Principali
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
🗺️ Implementazione Suggerita - Roadmap
- 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
Classe Contatto
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<string> Telefoni { get; set; } = new List<string>();
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 Rubrica - Gestione Contatti
// Classe per gestire la rubrica
public class Rubrica
{
private List<Contatto> contatti = new List<Contatto>();
private List<Contatto> cestino = new List<Contatto>();
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<Contatto> CercaPerNome(string nome)
{
return contatti.Where(c =>
c.Nome.Contains(nome, StringComparison.OrdinalIgnoreCase) ||
c.Cognome.Contains(nome, StringComparison.OrdinalIgnoreCase));
}
public IEnumerable<Contatto> CercaPerTelefono(string telefono)
{
return contatti.Where(c =>
c.Telefoni.Any(t => t.Contains(telefono)));
}
public IEnumerable<Contatto> CercaPerEmail(string email)
{
return contatti.Where(c =>
c.Email.Contains(email, StringComparison.OrdinalIgnoreCase));
}
public IEnumerable<Contatto> TuttiContatti()
{
return contatti.OrderBy(c => c.Cognome).ThenBy(c => c.Nome);
}
public IEnumerable<Contatto> Cestino()
{
return cestino;
}
}
RubricaFileManager - Persistenza Dati
// 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;
}
}
RubricaUI - Interfaccia Utente
// 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<Contatto> 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");
}
}
}
Program.cs - Main
// Programma principale
class Program
{
static void Main()
{
RubricaUI ui = new RubricaUI();
ui.Avvia();
}
}
🎓 Concetti Applicati nel Progetto
- 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.
Funzionalità Richieste:
- Operazioni di base (+, -, *, /)
- Potenza (x^y)
- Radice quadrata
- Logaritmo naturale
- Memoria per salvare/recuperare valori (M+, M-, MR, MC)
- Storico delle operazioni
💡 Suggerimento
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.
Funzionalità Richieste:
- 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
💡 Suggerimento
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.
Funzionalità da Aggiungere:
- 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
💡 Suggerimento
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
🎯 Consigli per i Progetti Avanzati
- 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)
🎯 Il Prossimo Passo
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! 🚀
🎓 Complimenti! Hai Completato il Corso
Nel corso hai imparato:
- Sintassi e fondamenti C#
- Programmazione orientata agli oggetti
- Gestione dati e collezioni
- File I/O e persistenza
- Best practices e pattern
Continua il tuo percorso:
- Completa i progetti proposti
- Contribuisci a progetti open source
- Approfondisci ASP.NET, WPF, Xamarin
- Partecipa alle community
- Non smettere mai di imparare!