Tipi generici (classi e metodi)
Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 42 di 70.
I generics ti permettono di scrivere classi e metodi che funzionano con qualsiasi tipo di dato mantenendo la sicurezza dei tipi. Invece di scrivere classi separate per IntList, StringList e DoubleList, scrivi un’unica classe generica che li gestisce tutti.
Una classe generica usa un parametro di tipo, in genere chiamato T, racchiuso tra parentesi angolari:
public class Box<T>
{
private T content;
public void Store(T item) => content = item;
public T Retrieve() => content;
}
// Utilizzo con tipi diversi
Box<int> intBox = new Box<int>();
intBox.Store(42);
Box<string> stringBox = new Box<string>();
stringBox.Store("Hello");Quando crei Box<int>, il compilatore sostituisce ogni T con int. Questo fornisce un controllo dei tipi in fase di compilazione: non puoi memorizzare accidentalmente una stringa in un contenitore int.
I metodi generici funzionano in modo simile e consentono a un singolo metodo di operare su tipi diversi:
public static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
int x = 1, y = 2;
Swap(ref x, ref y); // x=2, y=1Il compilatore deduce il tipo dagli argomenti, quindi non devi scrivere esplicitamente Swap<int>. I generics sono alla base di collezioni come List<T> e Dictionary<TKey, TValue> e consentono di scrivere codice riutilizzabile e sicuro rispetto ai tipi.
Sfida
FacileCreiamo un sistema generico Storage<T> in grado di contenere e gestire elementi di qualsiasi tipo. Creerai una classe contenitore riutilizzabile che dimostra la potenza dei generics: scrivila una volta e usala con interi, stringhe o qualsiasi altro tipo!
Organizzerai il codice in due file:
Storage.cs: crea una classe genericaStorage<T>nello spazio dei nomiDataStorage. Il contenitore deve:- Avere un array privato di tipo
Tper contenere gli elementi e una proprietàCountche tiene traccia del numero di elementi memorizzati - Accettare una capacità nel costruttore per inizializzare l'array interno
- Avere un metodo
Add(T item)che aggiunge un elemento se c'è spazio - Avere un metodo
Get(int index)che restituisce l'elemento all'indice specificato - Avere un metodo
GetAll()che restituisce tutti gli elementi memorizzati, uniti da", "
- Avere un array privato di tipo
Program.cs: nel file principale, mostra la tua classe generica in funzione con due tipi diversi. Crea unaStorage<int>e unaStorage<string>, aggiungi elementi a ciascuna e mostra che la stessa classe funziona senza problemi con entrambi i tipi.
Riceverai quattro input:
- Primo intero da memorizzare
- Secondo intero da memorizzare
- Prima stringa da memorizzare
- Seconda stringa da memorizzare
Crea un contenitore di interi con capacità 5 e un contenitore di stringhe con capacità 5. Aggiungi i due interi al contenitore di interi e le due stringhe al contenitore di stringhe.
Stampa l'output in questo formato:
Int storage: {GetAll()}
Int count: {Count}
First int: {Get(0)}
String storage: {GetAll()}
String count: {Count}
First string: {Get(0)}Per esempio, se gli input sono 42, 100, Hello e World, l'output dovrebbe essere:
Int storage: 42, 100
Int count: 2
First int: 42
String storage: Hello, World
String count: 2
First string: HelloNota che scrivi la classe Storage<T> una sola volta, ma funziona perfettamente sia con int che con string: questa è la magia dei generics! Il compilatore garantisce la sicurezza dei tipi, così non puoi aggiungere accidentalmente una stringa al contenitore di interi.
Provalo tu
using System;
using DataStorage;
class Program
{
public static void Main(string[] args)
{
// Leggi gli input
int num1 = Convert.ToInt32(Console.ReadLine());
int num2 = Convert.ToInt32(Console.ReadLine());
string str1 = Console.ReadLine();
string str2 = Console.ReadLine();
// TODO: Crea uno Storage<int> con capacità 5
// TODO: Aggiungi i due numeri interi allo storage degli interi
// TODO: Crea uno Storage<string> con capacità 5
// TODO: Aggiungi le due stringhe allo storage delle stringhe
// TODO: Stampa l'output nel formato richiesto
// Int storage: {GetAll()}
// Conteggio degli interi: {Count}
// Primo intero: {Get(0)}
// String storage: {GetAll()}
// String count: {Count}
// First string: {Get(0)}
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniNamespace e direttiveIntroduzione a classi e oggettiLa parola chiave "this"Metodi e parametriCampi e proprietàCostruttoriInizializzatori di oggettiRiepilogo - Calcolatrice semplice4Ereditarietà
Sintassi di base dell'ereditarietà (:)La parola chiave 'base'Parole chiave virtual e overrideClassi sealedLa classe base 'object'Riepilogo - Gerarchia dei dipendenti7Funzionalità avanzate
Sovraccarico degli operatoriIndicizzatori (this[])Override di ToString()Metodi di estensioneRiepilogo - Lista personalizzata10Pattern di progettazione Parte 1
Introduzione ai pattern di progettazioneSingleton thread-safePattern FactoryPattern Observer (eventi)Pattern Strategy2Proprietà e membri statici
Proprietà implementate automaticamenteProprietà di sola lettura e di sola scritturaCampi e metodi staticiClassi staticheMembri con corpo di espressione5Polimorfismo e interfacce
Polimorfismo a compile time e runtimeInterfaccia o classe astrattaInterfacce multipleInterfacce espliciteUpcasting e downcastingRipasso: calcolatore di forme8Concetti avanzati di programmazione a oggetti
Composizione invece dell'ereditarietàTipi generici (classi e metodi)Delegati ed eventiAttributi e reflectionIDisposable e istruzione usingNozioni di base sull'iniezione delle dipendenze11Pattern di progettazione, parte 2
Pattern del ComandoPattern dell’AdattatorePattern del DecoratorePattern Template MethodPattern dello StatoPattern Composito3Architettura delle classi
Dati di istanza vs staticiParole chiave 'readonly' e 'const'Campi di supportoRiepilogo - Gestore di conti bancari6Incapsulamento
Modificatori di accessoProprietà per l'incapsulamentoImplementazione dell'occultamento dei datiModelli di immutabilitàRiepilogo - Registri degli studentiEsercitati da solo: Compilatore C# online