È irragionevole aspettarsi che Any () * not * generi un'eccezione di riferimento null?


41

Quando crei un metodo di estensione puoi, ovviamente, chiamarlo su null. Ma, a differenza di una chiamata di metodo di istanza, chiamarlo su null non deve lanciare unNullReferenceException -> si controlla e gettarlo manualmente.

Per l'implementazione del metodo di estensione Linq, Any()Microsoft ha deciso di lanciare un ArgumentNullException( https://github.com/dotnet/corefx/blob/master/src/System.Linq/src/System/Linq/AnyAll.cs ).

Mi fa male dover scrivere if( myCollection != null && myCollection.Any() )

Mi sbaglio, come cliente di questo codice, aspettarmi che, ad esempio, ((int[])null).Any()debba tornare false?


41
in C # 6, puoi semplificare il tuo controllo se (myCollection? .Any () == true)
17 del 26

5
Anche in F #, che in realtà non usa valori null tranne l'interoperabilità con altri linguaggi .NET, null |> Seq.isEmptygenera System.ArgumentNullException: Value cannot be null. L'aspettativa sembra essere che non passerai valori indefiniti per qualcosa che dovrebbe esistere, quindi è ancora un'eccezione quando hai un valore nullo. Se è una questione di inizializzazione, inizierei con una sequenza vuota invece di a null.
Aaron M. Eshbach,

21
Ecco perché non dovresti tornare nullquando hai a che fare con le raccolte ma invece utilizzare una raccolta vuota in quei casi.
Bakuriu,

31
Bene, perché è nullo in primo luogo? Non vuoi che null sia considerato vuoto, perché non è vuoto, è qualcosa di completamente diverso. Forse vuoi che sia considerato vuoto nel tuo caso, ma l'aggiunta di quel genere di cose alla lingua porta a bug.
user253751

22
Devo sottolineare che ogni singolo metodo LINQ genera un argomento nullo. Anyè coerente.
Sebastian Redl,

Risposte:


157

Ho una borsa con dentro cinque patate. Ci sono .Any()patate nel sacco?

" " dici.<= true

Tiro fuori tutte le patate e le mangio. Ci sono .Any()patate nel sacco?

" No " dici.<= false

Incenerisco completamente la borsa nel fuoco. Ci sono delle .Any()patate nel sacco adesso?

" Non c'è borsa ."<= ArgumentNullException


3
Ma vagamente, non ci sono patate nella borsa? False implica False ... (Non sono in disaccordo, solo una seconda prospettiva).
D. Ben Knoble,

6
più praticamente, qualcuno ti consegna una scatola chiusa da una fonte sconosciuta. La confezione nella confezione contiene delle patate? Sono interessato solo a 2 scenari: A) c'è un sacchetto nella scatola che contiene patate, o B) non ci sono patate e / o nessuna borsa nella scatola. Semanticamente, sì, c'è una differenza tra null e empty, ma il 99% delle volte non mi interessa.
Dave Thieben,

6
Hai mangiato cinque patate crude ?? Consultare immediatamente un medico.
Oly

3
@Oly Dan le ha cucinate nel fuoco, prima di mangiare e usare quel fuoco per incenerire la borsa.
Ismael Miguel,

3
@ D.BenKnoble: Senza aver visto il bagagliaio della mia macchina, sei disposto a testimoniare che non ci sono corpi nel bagagliaio della mia macchina? No? Qual è la differenza tra controllare il bagagliaio e non trovare nulla o non controllare il bagagliaio? Non puoi semplicemente testimoniare ora, dato che in entrambi i casi avresti visto la stessa identica quantità di corpi? ... Questa è la differenza. Non puoi garantire qualcosa se non sei in grado di confermarlo in primo luogo. Supponi che i due siano equi, ma non è un dato di fatto. In alcuni casi, potrebbe esserci una differenza importante tra i due.
Flater

52

Prima di tutto, sembra che verrà lanciato quel codice sorgente ArgumentNullException, noNullReferenceException .

Detto questo, in molti casi sai già che la tua raccolta non è nulla, perché questo codice viene chiamato solo da un codice che sa che la raccolta esiste già, quindi non dovrai inserire il controllo null molto spesso. Ma se non sai che esiste, allora ha senso controllare prima di chiamarlo Any().

Mi sbaglio, come cliente di questo codice, aspettarmi che, ad esempio, ((int[])null).Any()debba tornare false?

Sì. La domanda che Any()risponde è "questa raccolta contiene elementi?" Se questa raccolta non esiste, allora la domanda stessa è priva di senso; non può contenere né non contenere nulla, perché non esiste.


18
@ChrisWohlert: il tuo intuito mi incuriosisce. Pensi anche che semanticamente, una persona inesistente sia una persona vuota, il cui nome è la stringa vuota e l'età è zero e così via? E pensi che un set contenente nullsia equivalente a un set contenente l'insieme vuoto (e viceversa)?
Ruakh,

17
@ChrisWohlert: Ovviamente un set può contenere un set vuoto; ma sembra che tu lo creda { null }e { {} }dovrebbe essere equivalente. Lo trovo affascinante; Non ci riesco affatto.
Ruakh,

9
In .Adduna nullcollezione dovrebbe in qualche modo creare una collezione anche per noi?
Matteo,

13
@ChrisWohlert "A è un set vuoto. B è un set contenente un'anguria. È A vuoto? Sì. B è vuoto? No. C è vuoto? Uhhh ..."
user253751

16
Punto pedante: non è il caso che, in teoria degli insiemi, un insieme inesistente sia un insieme vuoto. Il set vuoto esiste e qualsiasi set inesistente non lo è (e in effetti non è affatto nulla, dal momento che non esiste).
James_pic,

22

Null significa informazioni mancanti, non elementi.

Si potrebbe considerare in modo più ampio di evitare null - ad esempio, utilizzare uno degli enumerabili vuoti incorporati per rappresentare una raccolta senza elementi anziché null.

Se si restituisce null in alcune circostanze, è possibile modificarlo per restituire la raccolta vuota. (Altrimenti, se trovi null restituito da metodi di libreria (non tuoi), è un peccato, e li avvolgerei per normalizzarli.)

Vedi anche https://stackoverflow.com/questions/1191919/what-does-linq-return-when-the-results-are-empty


1
Ciò nullnon significa che nessun elemento sia una questione di utilizzo di una convenzione ragionevole. Basti pensare OLESTRINGS native, dove effettivamente fa sul serio.
Deduplicatore,

1
@Deduplicator, stai parlando della possibilità di Microsoft Object Linking and Embedding? Se ricordi, OLE è degli anni '90! Guardando più attualmente, molti linguaggi moderni (C #, Java, Swift) stanno fornendo strutture per eliminare / sradicare gli usi di null.
Erik Eidt,

2
@ErikEidt Lo stanno facendo, in parte, perché nullnon significa "informazioni mancanti". nullnon ha un'unica interpretazione significativa. Invece, si tratta di come lo tratti. nullviene talvolta utilizzato per "informazioni mancanti", ma anche per "nessun elemento" e anche per "si è verificato un errore" o "informazioni non inizializzate" o "informazioni contrastanti" o qualcosa di arbitrario e ad hoc.
Derek Elkins,

-1. Questa è una decisione presa dallo sviluppatore, non da teorie astratte. nullè assolutamente frequentemente usato per significare "nessun dato". A volte ha senso. Altre volte no.
jpmc26,

13

A parte la sintassi null-condizionale , c'è un'altra tecnica per alleviare questo problema: non lasciare mai che la tua variabile rimanganull .

Considera una funzione che accetta una raccolta come parametro. Se ai fini della funzione nulle vuoto sono equivalenti, puoi assicurarti che non contenga mai nullall'inizio:

public MyResult DoSomething(int a, IEnumerable<string> words)
{
    words = words ?? Enumerable.Empty<string>();

    if (!words.Any())
    {
        ...

Puoi fare lo stesso quando recuperi raccolte da un altro metodo:

var words = GetWords() ?? Enumerable.Empty<string>();

(Nota che nei casi in cui hai il controllo su una funzione come GetWordsenull è equivalente alla raccolta vuota, è preferibile restituire la raccolta vuota in primo luogo.)

Ora puoi eseguire qualsiasi operazione desideri sulla collezione. Ciò è particolarmente utile se è necessario eseguire molte operazioni che fallirebbero quando la raccolta è null, e nei casi in cui si ottiene lo stesso risultato eseguendo il ciclo o interrogando un enumerabile vuoto, consentirà di eliminare ifcompletamente le condizioni.


12

Sbaglio, come cliente di questo codice, aspettarmi che eg ((int []) null) .Any () dovrebbe restituire false?

Sì, semplicemente perché sei in C # e quel comportamento è ben definito e documentato.

Se stessi creando la tua libreria o se stavi utilizzando una lingua diversa con una diversa cultura delle eccezioni, sarebbe più ragionevole aspettarsi un falso.

Personalmente ritengo che return false sia un approccio più sicuro che rende il tuo programma più solido, ma almeno discutibile.


15
Quella "robustezza" è spesso un'illusione: se il codice che genera l'array inizia improvvisamente a generare NULL inaspettatamente a causa di un bug o di un altro problema, il codice "robusto" nasconderà il problema. A volte è un comportamento appropriato, ma non è un valore predefinito sicuro.
GoatInTheMachine,

1
@GoatInTheMachine - Non sono d'accordo sul fatto che sia un valore predefinito sicuro, ma hai ragione sul fatto che nasconde il problema e che tale comportamento a volte è indesiderabile. Nella mia esperienza, nascondere il problema (o fidarsi dei test di unità per rilevare i problemi di altri codici) è meglio che arrestare in modo anomalo l'app generando eccezioni impreviste. Voglio dire davvero: se il codice chiamante è abbastanza rotto da inviare null, qual è la possibilità che gestiscano correttamente le eccezioni?
Telastyn,

10
Se qualcosa non funziona, che si tratti del mio codice, di un altro collega o di un cliente, preferirei che il codice fallisse immediatamente e la gente lo sapesse piuttosto che continuare in uno stato potenzialmente incoerente per un periodo di tempo indeterminato. Essere in grado di farlo è ovviamente a volte un lusso e non sempre appropriato, ma è l'approccio che preferisco.
GoatInTheMachine,

1
@GoatInTheMachine - Sono d'accordo per molte cose, ma le collezioni tendono ad essere diverse. Trattare null come una raccolta vuota non è un comportamento terribilmente incoerente o sorprendente.
Telastyn,

8
Immagina di avere un array popolato da un documento JSON ricevuto tramite una richiesta Web e che in produzione uno dei tuoi client API ha improvvisamente un problema a causa del quale inviano attraverso JSON parzialmente non valido causandoti di deserializzare un array come NULL, preferiresti: il codice, nella peggiore delle ipotesi, ha generato un'eccezione di riferimento NULL nel momento in cui è arrivata la prima richiesta non valida, che vedresti nella registrazione e quindi dire immediatamente al client di correggere le richieste interrotte, O il tuo codice dice "oh, l'array è vuoto, niente fare!" e in silenzio ha scritto 'paniere acquisti non aveva articoli' nel db per alcune settimane?
GoatInTheMachine,

10

Se i ripetuti controlli null ti infastidiscono, puoi creare il tuo metodo di estensione 'IsNullOrEmpty ()', per rispecchiare il metodo String con quel nome e racchiudere sia il controllo null che la chiamata .Any () in una singola chiamata.

Altrimenti, la soluzione, menzionata da @ 17 di 26 in un commento sotto la tua domanda, è anche più breve del metodo "standard", e ragionevolmente chiara per chiunque abbia familiarità con la nuova sintassi null-condizionale.

if(myCollection?.Any() == true)

4
Puoi anche usare al ?? falseposto di == true. Questo mi sembrerebbe più esplicito (più pulito) dal momento che gestisce solo il caso di null, e in realtà non è più prolisso. Inoltre i ==controlli per i booleani di solito attivano il mio riflesso del vomito. =)
jpmc26

2
@ jpmc26: non so molto di C #. Perché non è myCollection?.Any()abbastanza?
Eric Duminil,

6
@EricDuminil A causa del modo in cui funziona l'operatore null-condizionale, myCollection?.Any()restituisce effettivamente un booleano nullable anziché un normale booleano (ovvero bool? Invece di bool). Non esiste una conversione implicita da bool? bool, ed è un bool che ci serve in questo esempio particolare (da testare come parte della ifcondizione). Pertanto, dobbiamo confrontare esplicitamente trueo utilizzare l'operatore a coalescenza nulla (??).
Steven Rands,

@ jpmc26 ?? false è più difficile da leggere di myCollection? .Any () == true. Indipendentemente dal tuo riflesso del vomito, == true è ciò che stai cercando di testare implicitamente. ?? false aggiunge solo ulteriore rumore e devi ancora fare la valutazione nella tua testa su cosa succede se null, che null == true fallirebbe, quasi senza che il lettore debba nemmeno essere consapevole del ?..
Ryan The Leach,

2
@RyanTheLeach Devo pensare molto più a fondo se ==funzionerà davvero. So già cosa succede intuitivamente con un booleano quando può essere solo trueo false; Non devo nemmeno pensarci. Ma buttati nullnel mix, e ora devo capire se ==è giusto. ??invece elimina semplicemente il nullcaso, riducendolo a truee falseche già capisci immediatamente. Per quanto riguarda il mio riflesso del vomito, quando lo vedo per la prima volta, il mio istinto immediato è quello di eliminarlo poiché di solito è inutile, cosa che non vuoi che accada.
jpmc26,

8

Sbaglio, come cliente di questo codice, aspettarmi che eg ((int []) null) .Any () dovrebbe restituire false?

Se ti chiedi delle aspettative devi pensare alle intenzioni.

null significa qualcosa di molto diverso da Enumerable.Empty<T>

Come menzionato nella risposta di Erik Eidt , esiste una differenza di significato tra nulluna raccolta vuota.

Diamo prima un'occhiata a come dovrebbero essere usati.

Il libro Framework Design Guidelines: Conventions, Idioms and Patterns for Reusable .NET Libraries, 2nd Edition scritto dagli architetti Microsoft Krzysztof Cwalina e Brad Abrams afferma le seguenti best practice:

X NON restituire valori null dalle proprietà della raccolta o dai metodi che restituiscono raccolte. Restituisce invece una raccolta vuota o una matrice vuota.

Considera la tua chiamata un metodo che alla fine sta ottenendo dati da un database: se ricevi un array vuoto o Enumerable.Empty<T>questo significa semplicemente che lo spazio del tuo campione è vuoto, cioè il tuo risultato è un set vuoto . La ricezione nullin questo contesto, tuttavia, significherebbe uno stato di errore .

Nella stessa linea di pensiero dell'analogia della patata di Dan Wilson , ha senso porre domande sui tuoi dati anche se si tratta di un set vuoto . Ma ha molto meno senso, se non c'è un set .


1
Il fatto che abbiano significati diversi dipende fortemente dal contesto. Spesso, ai fini di qualsiasi logica sia a portata di mano, rappresentano concetti equivalenti. Non sempre , ma spesso.
jpmc26,

1
@ jpmc26: Penso che il punto di questa risposta sia dire che codificando le linee guida per c # hanno un significato diverso. Puoi sempre correggere il codice in cui null e empty sono uguali se lo desideri. E in alcuni casi puoi anche fare la stessa cosa se è nulla o vuoto, ma ciò non significa che significano la stessa cosa.
Chris,

@ Chris E sto dicendo che le linee guida per la codifica da parte di persone che hanno progettato la lingua non possono essere utilizzate in sostituzione della valutazione del codice nel contesto delle tue esigenze, delle librerie che stai utilizzando e degli altri sviluppatori con cui lavori. L'idea che non saranno mai equivalenti nel contesto è l'idealismo pie-in-the-sky. Potrebbero anche non essere equivalenti per i dati a portata di mano in generale, ma essere equivalenti per generare un risultato in alcune funzioni specifiche che stai scrivendo; in tal caso, è necessario supportare entrambi ma assicurarsi che generino lo stesso risultato.
jpmc26,

Potrei essere confuso da quello che stai dicendo, ma quando null e empty sono equivalenti per generare un risultato, non vedo perché non dovresti semplicemente usare separati è null ed è controlli vuoti piuttosto che desiderare un metodo che faccia entrambi contemporaneamente ma non ti permette di distinguerli in altre situazioni ...
Chris,

@Chris mi riferisco ad avere contesti diversi (che spesso corrispondono a ambiti). Considera una funzione per esempio. nulle vuoto può comportare lo stesso valore restituito per la funzione, ma ciò non significa che nullvuoto significa esattamente la stessa cosa nell'ambito di chiamata.
jpmc26,

3

Ci sono molte risposte che spiegano perché nulle vuoti sono opinioni diverse e sufficienti che cercano di spiegare entrambi perché dovrebbero essere trattati in modo diverso o meno. Tuttavia stai chiedendo:

Sbaglio, come cliente di questo codice, aspettarmi che eg ((int []) null) .Any () dovrebbe restituire false?

È un'aspettativa perfettamente ragionevole . Hai ragione come qualcun altro che sostiene il comportamento attuale. Concordo con l'attuale filosofia di attuazione, ma i fattori trainanti non sono - solo - basati su considerazioni fuori contesto.

Dato che Any()senza predicato è essenzialmente Count() > 0allora cosa ti aspetti da questo frammento?

List<int> list = null;
if (list.Count > 0) {}

O un generico:

List<int> list = null;
if (list.Foo()) {}

Suppongo che ti aspetti NullReferenceException.

  • Any()è un metodo di estensione, dovrebbe integrarsi senza problemi con l' oggetto esteso quindi lanciare un'eccezione è la cosa meno sorprendente.
  • Non tutti i linguaggi .NET supportano metodi di estensione.
  • Puoi sempre chiamare Enumerable.Any(null)e sicuramente ti aspetti ArgumentNullException. È lo stesso metodo e deve essere coerente, possibilmente, con TUTTO il resto del Framework.
  • L'accesso a un nulloggetto è un errore di programmazione , framework non dovrebbe imporre null come valore magico . Se lo usi in questo modo, è tua responsabilità occupartene.
  • È supponente , tu pensi in un modo e io penso in un altro modo. Il quadro dovrebbe essere il più nonopinionato possibile.
  • Se hai un caso speciale, devi essere coerente : devi prendere decisioni sempre più ponderate su tutti gli altri metodi di estensione: se Count()sembra una decisione facile, Where()non lo è. Che dire Max()? Genera un'eccezione per un elenco VUOTO, non dovrebbe lanciare anche per nulluno?

Ciò che i progettisti di biblioteche hanno fatto prima di LINQ è stato introdurre metodi espliciti quando nullè un valore valido (ad esempio String.IsNullOrEmpty()), quindi HANNO dovuto essere coerenti con la filosofia di progettazione esistente . Detto questo, anche se abbastanza banale da scrivere, due metodi EmptyIfNull()e EmptyOrNull()potrebbero essere utili.


1

Jim dovrebbe lasciare le patate in ogni sacco. Altrimenti lo ucciderò.

Jim ha una borsa con dentro cinque patate. Ci sono .Any()patate nel sacco?

"Sì" dici. <= vero

Ok, questa volta Jim vive.

Jim prende tutte le patate e le mangia. Ci sono. () Patate nella borsa?

"No" dici. <= false

È ora di uccidere Jim.

Jim incenerisce completamente la borsa nel fuoco. Ci sono. () Patate nella borsa ora?

"Non c'è borsa." <= ArgumentNullException

Jim dovrebbe vivere o morire? Beh, non ci aspettavamo questo, quindi ho bisogno di una sentenza. Lasciare che Jim riesca a risolvere questo problema o no?

Puoi usare le annotazioni per segnalare che non stai sopportando shenanigani nulli in questo modo.

public bool Any( [NotNull] List bag ) 

Ma la tua catena di strumenti deve supportarla. Ciò significa che probabilmente finirai comunque per scrivere assegni.


0

Se questo ti disturba così tanto, ti suggerisco un semplice metodo di estensione.

static public IEnumerable<T> NullToEmpty<T>(this IEnumerable<T> source)
{
    return (source == null) ? Enumerable.Empty<T>() : source;
}

Ora puoi farlo:

List<string> list = null;
var flag = list.NullToEmpty().Any( s => s == "Foo" );

... e flag verrà impostato su false.


2
Più naturale scrivere l' returnaffermazione come:return source ?? Enumerable.Empty<T>();
Jeppe Stig Nielsen,

Questo non risponde alla domanda posta.
Kenneth K.,

@ KennethK.ma sembra risolvere il problema presentato.
RQDQ,

0

Questa è una domanda sui metodi di estensione di C # e sulla loro filosofia di progettazione, quindi penso che il modo migliore per rispondere a questa domanda sia di citare la documentazione di MSDN sullo scopo dei metodi di estensione :

I metodi di estensione consentono di "aggiungere" metodi a tipi esistenti senza creare un nuovo tipo derivato, ricompilare o modificare in altro modo il tipo originale. I metodi di estensione sono un tipo speciale di metodo statico, ma vengono chiamati come se fossero metodi di istanza sul tipo esteso. Per il codice client scritto in C #, F # e Visual Basic, non esiste alcuna differenza apparente tra la chiamata di un metodo di estensione e i metodi che sono effettivamente definiti in un tipo.

...

In generale, si consiglia di implementare i metodi di estensione con parsimonia e solo quando è necessario. Quando possibile, il codice client che deve estendere un tipo esistente dovrebbe farlo creando un nuovo tipo derivato dal tipo esistente. Per ulteriori informazioni, vedere Ereditarietà.

Quando si utilizza un metodo di estensione per estendere un tipo di cui non è possibile modificare il codice sorgente, si corre il rischio che una modifica dell'implementazione del tipo causi l'interruzione del metodo di estensione.

Se si implementano metodi di estensione per un determinato tipo, tenere presente i seguenti punti:

  • Un metodo di estensione non verrà mai chiamato se ha la stessa firma di un metodo definito nel tipo.
  • I metodi di estensione vengono portati nell'ambito a livello di spazio dei nomi. Ad esempio, se si hanno più classi statiche che contengono metodi di estensione in un singolo spazio dei nomi denominato Extensions, saranno tutti inclusi nell'ambito della using Extensions;direttiva.

Per riassumere, i metodi di estensione sono progettati per aggiungere metodi di istanza a un tipo particolare, anche quando gli sviluppatori non possono farlo direttamente. E poiché i metodi di istanza sovrascriveranno sempre i metodi di estensione se presenti (se chiamati usando la sintassi del metodo di istanza), questo dovrebbe essere fatto solo se non è possibile aggiungere direttamente un metodo o estendere la classe. *

In altre parole, un metodo di estensione dovrebbe agire esattamente come farebbe un metodo di istanza, perché potrebbe finire per diventare un metodo di istanza da alcuni client. E poiché un metodo di istanza dovrebbe essere lanciato se l'oggetto su cui viene chiamato è null, così dovrebbe essere il metodo di estensione.


* Come nota a margine, questa è esattamente la situazione che i progettisti di LINQ hanno affrontato: quando è stato rilasciato C # 3.0, c'erano già milioni di clienti che stavano usando System.Collections.IEnumerablee System.Collections.Generic.IEnumerable<T>, sia nelle loro collezioni che nei foreachloop. Queste classi restituiti IEnumeratoroggetti che avevano solo i due metodi Currente MoveNext, quindi aggiungendo eventuali metodi di istanza richieste addizionali, come Count, Anyecc, sarebbe rompendo questi milioni di clienti. Quindi, al fine di fornire questa funzionalità (soprattutto perché può essere implementata in termini diCurrent e MoveNextcon relativa facilità), l'hanno rilasciata come metodo di estensione, che può essere applicato a qualsiasi attualmente esistenteIEnumerableistanza e può anche essere implementato dalle classi in modi più efficienti. Se i progettisti di C # avessero deciso di rilasciare LINQ dal primo giorno, sarebbe stato fornito come metodo di istanza diIEnumerablee probabilmente avrebbero progettato un qualche tipo di sistema per fornire implementazioni di interfaccia predefinite di tali metodi.


0

Penso che il punto saliente qui sia che restituendo false invece di lanciare un'eccezione, offuschi le informazioni che potrebbero essere rilevanti per i futuri lettori / modificatori del tuo codice.

Se è possibile che l'elenco sia nullo, suggerirei di avere un percorso logico separato per quello, poiché altrimenti in futuro qualcuno potrebbe aggiungere una logica basata sull'elenco (come un add) all'altro {} del tuo if, risultando in un eccezione indesiderata che non avevano motivo di prevedere.

La leggibilità e la manutenibilità vincono "Devo scrivere una condizione in più" ogni volta.


0

Come regola generale, scrivo la maggior parte del mio codice per presumere che il chiamante sia responsabile di non consegnarmi dati null, principalmente per i motivi indicati in Say No to Null (e altri post simili). Il concetto di null spesso non è ben compreso e, per questo motivo, è consigliabile inizializzare le variabili in anticipo, per quanto pratico. Supponendo che tu stia lavorando con un'API ragionevole, idealmente non dovresti mai recuperare un valore null, quindi non dovresti mai controllare null. Il punto di null, come hanno affermato altre risposte, è assicurarsi di disporre di un oggetto valido (ad es. Una "borsa") con cui lavorare prima di continuare. Questa non è una caratteristica di Any, ma piuttosto una caratteristica della linguasi. Non è possibile eseguire la maggior parte delle operazioni su un oggetto null, perché non esiste. È come se ti chiedessi di guidare fino al negozio nella mia macchina, tranne che non possiedo un'auto, quindi non hai modo di usare la mia macchina per guidare fino al negozio. Non ha senso eseguire un'operazione su qualcosa che letteralmente non esiste.

Esistono casi pratici per l'utilizzo di null, ad esempio quando non hai letteralmente le informazioni richieste disponibili (ad esempio se ti chiedessi quale sia la mia età, la scelta più probabile con cui rispondere a questo punto è "Non lo so ", che è un valore null). Tuttavia, nella maggior parte dei casi, dovresti almeno sapere se le variabili sono inizializzate o meno. E se non lo fai, ti consiglio di stringere il tuo codice. La prima cosa che faccio in qualsiasi programma o funzione è inizializzare un valore prima di usarlo. È raro che abbia bisogno di controllare i valori null, perché posso garantire che le mie variabili non siano null. È una buona abitudine entrare in contatto e più frequentemente ti ricordi di inizializzare le tue variabili, meno frequentemente devi verificare la presenza di null.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.