Domanda

Ho cercato una buona guida su questo da quando il concetto è stato introdotto in .net 2.0.

Perché dovrei mai voler usare tipi di dati non annullabili in c #? (Una domanda migliore è perché non dovrei scegliere i tipi annullabili per impostazione predefinita e utilizzare i tipi non annullabili solo quando ciò ha esplicitamente senso.)

Esiste un impatto sulle prestazioni "significativo" nella scelta di un tipo di dati nullable rispetto al suo peer non nullable?

Preferisco di gran lunga controllare i miei valori rispetto a null anziché a Guid.empty, string.empty, DateTime.MinValue, < = 0, ecc., e lavorare con tipi nullable in generale. E l'unica ragione per cui non scelgo tipi nulli più spesso è la sensazione di prurito nella parte posteriore della mia testa che mi fa sentire che è più della compatibilità all'indietro che forza quel "" carattere per consentire esplicitamente un valore nullo.

C'è qualcuno là fuori che sceglie sempre (quasi sempre) tipi nulli o non nulli?

Grazie per il tuo tempo,

È stato utile?

Soluzione

Il motivo per cui non dovresti sempre usare tipi nullable è che a volte sei in grado di garantire che un valore verrà inizializzato. E dovresti provare a progettare il tuo codice in modo che ciò avvenga il più spesso possibile. Se non è possibile che un valore non possa essere inizializzato, allora non c'è motivo per cui null dovrebbe essere un valore legale per esso. A titolo di esempio molto semplice, considera questo:

List<int> list = new List<int>()
int c = list.Count;

Questo è sempre valido. Non è possibile in alcun modo c non essere inizializzato. Se fosse stato trasformato in int?, avresti effettivamente comunicato ai lettori il codice & Quot; questo valore potrebbe essere nullo. Assicurati di controllare prima di usarlo & Quot ;. Ma sappiamo che ciò non può mai accadere, quindi perché non esporre questa garanzia nel codice?

Hai assolutamente ragione nei casi in cui un valore è facoltativo. Se disponiamo di una funzione che può o non può restituire una stringa, restituisce null. Non restituire string.Empty (). Non restituire & Quot; valori magici & Quot ;.

Ma non tutti i valori sono opzionali. E rendere tutto opzionale rende il resto del codice molto più complicato (aggiunge un altro percorso di codice che deve essere gestito).

Se puoi specificamente garantire che questo valore sia sempre valido, perché buttare via queste informazioni? Questo è quello che fai rendendolo un tipo nullable. Ora il valore potrebbe esistere o meno e chiunque utilizzi il valore dovrà gestire entrambi i casi. Ma sai che solo uno di questi casi è possibile in primo luogo. Quindi fai un favore agli utenti del tuo codice e rifletti questo fatto nel tuo codice. Tutti gli utenti del codice possono quindi fare affidamento sul valore valido e devono gestire solo un singolo caso anziché due.

Altri suggerimenti

Perché è scomodo controllare sempre se il tipo nullable è null.

Ovviamente ci sono situazioni in cui un valore è veramente facoltativo, e in quei casi ha senso usare un tipo nullable piuttosto che numeri magici ecc., ma dove possibile proverei ad evitarli.

// nice and simple, this will always work
int a = myInt;

// compiler won't let you do this
int b = myNullableInt;

// compiler allows these, but causes runtime error if myNullableInt is null
int c = (int)myNullableInt;
int d = myNullableInt.Value;    

// instead you need to do something like these, cumbersome and less readable
int e = myNullableInt ?? defaultValue;
int f = myNullableInt.HasValue ? myNullableInt : GetValueFromSomewhere();

Penso che i progettisti del linguaggio ritengano che "i tipi di riferimento essendo nullable per impostazione predefinita" sia stato un errore e che il non annullabile sia l'unico valore predefinito ragionevole e dovresti optare per la nullità. (È così in molti linguaggi funzionali moderni.) & Quot; null & Quot; di solito è un mucchio di problemi.

Sembra che tu abbia 2 domande diverse ...

  

Perché mai dovrei voler usare tipi di dati non annullabili in C #?

Semplice, perché i dati sul tipo di valore su cui fai affidamento sono garantiti dal compilatore per avere effettivamente un valore!

  

Perché non dovrei scegliere i tipi annullabili per impostazione predefinita e utilizzare i tipi non annullabili solo quando ciò ha esplicitamente senso?

Come Joel ha già accennato, un tipo può essere nullo solo se è un tipo di riferimento. I tipi di valore sono garantiti dal compilatore per avere un valore. Se il tuo programma dipende da una variabile per avere un valore, questo è il comportamento che vorrai non scegliendo un tipo nullable.

Ovviamente, quando i tuoi dati provengono da un luogo diverso dal tuo programma, tutte le scommesse sono disattivate. Il miglior esempio è da un database. I campi del database possono essere null, quindi si vorrebbe che la variabile del programma imitasse questo valore, non solo creare un & Quot; magic & Quot; valore (ovvero -1, 0 o qualsiasi altra cosa) che " rappresenta " <=>. Puoi farlo con tipi nullable.

Sebbene i valori null possano essere utili per l'uso come " non inizializzato-ancora " o " non specificato " valori, rendono il codice più complesso, principalmente perché stai sovraccaricando il significato di null e la variabile (numero-o-null vs. solo-un-numero).

I valori NULL sono favoriti da molti progettisti di database e programmatori di database SQL, ma con una piccola modifica nel pensare al problema puoi eliminare i valori null e in realtà avere un codice più semplice e affidabile (ad esempio, non preoccuparti di NullReferenceException s ).

In realtà c'è una grande domanda per un " T! " operatore che rende qualsiasi tipo di riferimento non annullabile, simile a come " T? " rende nulli i tipi di valore e Anders Hejlsberg, l'inventore di C #, desiderava aver incluso l'abilità.

Vedi anche la domanda Why is & # 8220; null # 8221 &; presente in C # e Java?

Tendo a usare i tipi Nullable ovunque abbiano senso - non mi preoccuperò delle prestazioni fino a quando non sarà un problema, quindi riparerò le poche aree in cui si trovano e ne avrò finito.

Tuttavia, trovo anche che in generale, la maggior parte dei miei valori finiscono per essere non annullabili. In effetti, ci sono molte volte in cui vorrei davvero un NotNullable che posso usare con i tipi di riferimento per scoprire un problema null quando ottengo il null, non più tardi quando provo ad usarlo.

L'unica volta in cui un Tipo Nullable dovrebbe mai essere usato, è nel caso in cui un certo campo in una tabella del database richieda assolutamente che un null sia inviato o ricevuto dall'applicazione ad un certo punto. Anche in questo caso, si dovrebbe sempre cercare di trovare un modo per aggirare usando il Tipo Nullable. Bool non è sempre il tuo migliore amico.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top