Panoramica di classi, struct e record in C#

In C# la definizione di un tipo, ovvero una classe, uno struct o un record, è simile a un progetto che specifica le operazioni che il tipo può eseguire. Un oggetto è essenzialmente un blocco di memoria che è stato allocato e configurato in base al progetto iniziale. Questo articolo offre una panoramica di questi progetti e delle relative funzionalità. Nell'articolo successivo di questa serie vengono presentati gli oggetti.

Incapsulamento

L'incapsulamento è talvolta definito come il principio fondamentale della programmazione orientata agli oggetti. Una classe o uno struct può specificare il modo in cui ognuno dei membri è accessibile per il codice all'esterno della classe o dello struct. I metodi e le variabili destinati a non essere usati all'esterno della classe o dell'assembly possono essere nascosti per limitare il rischio di errori di codifica o esiti dannosi. Per altre informazioni, vedere l'esercitazione sulla programmazione orientata agli oggetti.

Membri

I membri di un tipo includono tutti i metodi, i campi, le costanti, le proprietà e gli eventi. In C# non esistono variabili o metodi globali come in altri linguaggi. Anche il punto di ingresso di un programma, il metodo Main, deve essere dichiarato all'interno di una classe o di uno struct (in modo implicito quando si usano istruzioni di primo livello).

Di seguito sono elencati tutti i tipi di membri che possono essere dichiarati in una classe, uno struct o un record.

  • Campi
  • Costanti
  • Proprietà
  • Metodi
  • Costruttori
  • Eventi
  • Finalizzatori
  • Indicizzatori
  • Operatori
  • Tipi annidati

Per altre informazioni, vedere Membri.

Accessibilità

Alcuni metodi e proprietà sono progettati in modo da essere chiamabili o accessibili da codice esterno alla classe o allo struct, noto come codice client. Altri metodi e proprietà possono invece essere usati esclusivamente all'interno della classe o del tipo struct. Questa distinzione è importante per limitare l'accessibilità del codice in modo che solo il codice client desiderato possa raggiungerlo. Specificare il modo in cui i tipi e i relativi membri sono accessibili al codice client usando i modificatori di accesso seguenti:

L'accessibilità predefinita è private.

Ereditarietà

Le classi (ma non i tipi struct) supportano il concetto di ereditarietà. Una classe che deriva da un'altra classe definita classe di base contiene automaticamente tutti i membri pubblici, protetti e interni della classe di base, ad eccezione di costruttori e finalizzatori.

Le classi possono essere dichiarate come astratte. Ciò significa che uno o più metodi di tali classi sono privi di implementazione. Anche se non è possibile crearne direttamente un'istanza, le classi astratte possono svolgere la funzione di classi di base per altre classi che forniscono l'implementazione mancante. Le classi possono anche essere dichiarate come sealed per impedire che altre classi ereditino da esse.

Per altre informazioni, vedere Ereditarietà e Polimorfismo.

Interfacce

Le classi, gli struct e i record possono implementare più interfacce. Implementare un'interfaccia significa che il tipo implementa tutti i metodi definiti nell'interfaccia. Per altre informazioni, vedere Interfacce.

Tipi generici

Le classi, gli struct e i record possono essere definiti con uno o più parametri di tipo. Il codice client fornisce il tipo quando ne crea un'istanza. Ad esempio, la classe List<T> nello spazio dei nomi System.Collections.Generic viene definita con un solo parametro di tipo. Il codice client crea un'istanza di List<string> o List<int> per specificare il tipo che sarà contenuto nell'elenco. Per altre informazioni, vedere Generics.

Tipi statici

Le classi (ma non gli struct o i record) possono essere dichiarate come static. Una classe statica può contenere solo membri statici e non è possibile crearne un'istanza con la parola chiave new. Una copia della classe viene caricata in memoria durante il caricamento del programma e i relativi membri sono accessibili tramite il nome della classe. Le classi, gli struct e i record possono contenere membri statici. Per altre informazioni, vedere Classi statiche e membri di classi statiche.

Tipi annidati

Una classe, uno struct o un record può essere annidato all'interno di un'altra classe, struct o record. Per altre informazioni, vedere Tipi annidati.

Tipi parziali

È possibile definire una parte di una classe, un tipo struct o un metodo in un file di codice e un'altra parte in un file di codice separato. Per altre informazioni, vedere Classi e metodi parziali.

Inizializzatori di oggetti

È possibile creare un'istanza e inizializzare oggetti classe o struct e raccolte di oggetti assegnando valori alle relative proprietà. Per altre informazioni, vedere Come inizializzare gli oggetti usando un inizializzatore di oggetti.

Tipi anonimi

In situazioni in cui non è utile o necessario creare una classe denominata si usano tipi anonimi. I tipi anonimi vengono definiti dai relativi membri dati denominati. Per altre informazioni, vedere Tipi anonimi.

Metodi di estensione

È possibile "estendere" una classe senza creare una classe derivata creando un tipo separato. Tale tipo contiene metodi che possono essere chiamati come se appartenessero al tipo originale. Per altre informazioni, vedere Metodi di estensione.

Variabili locali tipizzate in modo implicito

All'interno di un metodo di classe o struct è possibile usare la tipizzazione implicita per indicare al compilatore di determinare il tipo di una variabile in fase di compilazione. Per altre informazioni, vedere var (Riferimenti per C#).

Record

È possibile aggiungere il modificatore record a una classe o a uno struct. I record sono tipi con comportamento predefinito per l'uguaglianza basata su valori. Un record (record class o record struct) fornisce le funzionalità seguenti:

  • Sintassi concisa per la creazione di un tipo riferimento con proprietà non modificabili.
  • Uguaglianza di valori. Due variabili di un tipo di record sono uguali se hanno lo stesso tipo e se, per ogni campo, i valori in entrambi i record sono uguali. Le classi usano l'uguaglianza dei riferimenti: due variabili di un tipo di classe sono uguali se fanno riferimento allo stesso oggetto.
  • Sintassi concisa per la mutazione non distruttiva. Un'espressione with consente di creare una nuova istanza di record che rappresenta una copia di un'istanza esistente, ma con i valori delle proprietà specificati modificati.
  • Formattazione predefinita per la visualizzazione. Il metodo ToString stampa il nome del tipo di record e i nomi e i valori delle proprietà pubbliche.
  • Supporto per le gerarchie di ereditarietà nelle classi di record. Le classi di record supportano l'ereditarietà. Gli struct di record non supportano l'ereditarietà.

Per altre informazioni, vedere Record.

Specifiche del linguaggio C#

Per altre informazioni, vedere la specifica del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.