Campi (Guida per programmatori C#)

Un campo è una variabile di qualsiasi tipo che viene dichiarata direttamente in una classe o struct. I campi sono membri del rispettivo tipo contenitore.

Una classe o struct può includere campi di istanza, campi statici o entrambi. I campi di istanza sono specifici di un'istanza di tipo. Se si ha una classe T con un campo di istanza F, è possibile creare due oggetti di tipo T e modificare il valore di F in ciascun oggetto senza modificare il valore nell'altro oggetto. Al contrario, un campo statico appartiene al tipo stesso ed è condiviso tra tutte le istanze del tipo. È possibile accedere al campo statico solo usando il nome del tipo. Se si accede al campo statico con un nome di istanza, viene visualizzato l'errore CS0176 in fase di compilazione.

In genere, è consigliabile dichiarare l'accessibilità private o protected per i campi. I dati che il tipo espone al codice client devono essere forniti tramite metodi, proprietà e indicizzatori. Usando questi costrutti per l'accesso indiretto ai campi interni, è possibile evitare valori di input non validi. Un campo privato che archivia i dati esposti da una proprietà pubblica è chiamato archivio di backup o campo sottostante. È possibile dichiarare i campi public, ma non è possibile impedire al codice che usa il tipo di impostare tale campo su un valore non valido o modificare in altro modo i dati di un oggetto.

Di solito i campi archiviano dati che devono essere accessibili a più metodi del tipo e devono essere archiviati per un tempo maggiore rispetto alla durata di ogni singolo metodo. Ad esempio, un tipo che rappresenta una data di calendario potrebbe contenere tre campi interi: uno per il mese, uno per il giorno e uno per l'anno. Le variabili che vengono usate solo all'interno dell'ambito di un singolo metodo devono essere dichiarate come variabili locali all'interno del corpo del metodo stesso.

I campi vengono dichiarati nella classe o nel blocco struct specificando il livello di accesso, seguito dal tipo e dal nome del campo. Ad esempio:

public class CalendarEntry
{

    // private field (Located near wrapping "Date" property).
    private DateTime _date;

    // Public property exposes _date field safely.
    public DateTime Date
    {
        get
        {
            return _date;
        }
        set
        {
            // Set some reasonable boundaries for likely birth dates.
            if (value.Year > 1900 && value.Year <= DateTime.Today.Year)
            {
                _date = value;
            }
            else
            {
                throw new ArgumentOutOfRangeException("Date");
            }
        }
    }

    // public field (Generally not recommended).
    public string? Day;

    // Public method also exposes _date field safely.
    // Example call: birthday.SetDate("1975, 6, 30");
    public void SetDate(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        // Set some reasonable boundaries for likely birth dates.
        if (dt.Year > 1900 && dt.Year <= DateTime.Today.Year)
        {
            _date = dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }

    public TimeSpan GetTimeSpan(string dateString)
    {
        DateTime dt = Convert.ToDateTime(dateString);

        if (dt.Ticks < _date.Ticks)
        {
            return _date - dt;
        }
        else
        {
            throw new ArgumentOutOfRangeException("dateString");
        }
    }
}

Per accedere a un campo in un'istanza, aggiungere un punto dopo il nome dell'istanza, seguito dal nome del campo, come in instancename._fieldName. Ad esempio:

CalendarEntry birthday = new CalendarEntry();
birthday.Day = "Saturday";

È possibile assegnare a un campo un valore iniziale usando l'operatore di assegnazione quando il campo viene dichiarato. Per assegnare automaticamente il campo Day a "Monday", ad esempio, è necessario dichiarare Day come nell'esempio seguente:

public class CalendarDateWithInitialization
{
    public string Day = "Monday";
    //...
}

I campi vengono inizializzati immediatamente prima della chiamata del costruttore per l'istanza dell'oggetto. Se il costruttore assegna il valore di un campo, sovrascriverà qualsiasi valore assegnato nella dichiarazione del campo. Per altre informazioni, vedere Uso dei costruttori.

Nota

Un inizializzatore di campo non può fare riferimento ad altri campi di istanza.

I campi possono essere contrassegnati come public, private, protected, internal, protected internal o private protected. Questi modificatori di accesso definiscono in che modo gli utenti del tipo possono accedere ai campi. Per altre informazioni, vedere Modificatori di accesso.

È possibile facoltativamente dichiarare un campo come static. I campi statici sono disponibili per i chiamanti in qualsiasi momento, anche se non esiste alcuna istanza del tipo. Per altre informazioni, vedere Classi statiche e membri di classi statiche.

È possibile dichiarare un campo come readonly. A un campo di sola lettura può essere assegnato un valore solo durante l'inizializzazione o in un costruttore. Un campo static readonly è simile a una costante, a parte il fatto che il compilatore C# non ha accesso al valore di un campo statico di sola lettura in fase di compilazione, ma solo in fase di esecuzione. Per altre informazioni, vedere Costanti.

È possibile dichiarare un campo come required. Un campo obbligatorio deve essere inizializzato dal costruttore o da un inizializzatore di oggetto quando viene creato un oggetto. Aggiungere l'attributo System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute a qualsiasi dichiarazione del costruttore che inizializza tutti i membri necessari.

Il modificatore required non può essere combinato con il modificatore readonly nello stesso campo. Tuttavia, la proprietà può essere solo required e init.

A partire da C# 12, i parametri del costruttore primario sono un'alternativa alla dichiarazione dei campi. Quando il tipo ha dipendenze che devono essere fornite all'inizializzazione, è possibile creare un costruttore primario che fornisca tali dipendenze. Questi parametri possono essere acquisiti e usati al posto dei campi dichiarati nei tipi. Nel caso dei tipi record, i parametri del costruttore primario vengono visualizzati come proprietà pubbliche.

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#.

Vedi anche