Si consideri:
-
Lingua,
-
quadro,
-
Contesto.
1. Lingua
Usare ∞ può essere una soluzione per un massimo.
-
JavaScript, ad esempio, ha un infinito. C # non1.
-
Ada, ad esempio, ha intervalli. C # no.
In C #, c'è int.MaxValue
, ma non puoi usarlo nel tuo caso. int.MaxValue
è il numero intero massimo, 2.147.483.647. Se nel tuo codice, hai un valore massimo di qualcosa, come una pressione massima accettata prima che qualcosa esploda, utilizzando 2.147.483.647 non ha senso.
2. Quadro
.NET Framework è piuttosto incoerente su questo punto e il suo uso di valori magici può essere criticato.
Ad esempio, "Hello".IndexOf("Z")
restituisce un valore magico -1
. forse rende più facile (o?) Manipolare il risultato:
int position = "Hello".IndexOf("Z");
if (position > 0)
{
DoSomething(position);
}
anziché utilizzare una struttura personalizzata:
SearchOccurrence occurrence = "Hello".IndexOf("Z");
if (occurrence.IsFound)
{
DoSomething(occurrence.StartOffset);
}
ma non è affatto intuitivo. Perché -1
e non -123
? Un principiante potrebbe anche pensare erroneamente che 0
significhi "Non trovato" o semplicemente errato (position >= 0)
.
3. Contesto
Se il tuo codice è correlato ai timeout nei socket di rete, l'utilizzo di qualcosa che è stato utilizzato da tutti per decenni per essere coerente non è una cattiva idea . Soprattutto, 0
per un timeout è molto chiaro: è un valore che non può essere zero. L'uso di una classe personalizzata in questo caso può rendere le cose più difficili da comprendere:
class Timeout
{
// A value indicating whether there is a timeout.
public bool IsTimeoutEnabled { get; set; }
// The duration of the timeout, in milliseconds.
public int Duration { get; set; }
}
- Posso impostare
Duration
su 0 se IsTimeoutEnabled
è vero?
- Se
IsTimeoutEnabled
è false, cosa succede se imposto Duration
su 100?
Questo può portare a più errori. Immagina il seguente pezzo di codice:
this.currentOperation.Timeout = new Timeout
{
// Set the timeout to 200 ms.; we don't want this operation to be longer than that.
Duration = 200,
};
this.currentOperation.Run();
L'operazione viene eseguita per dieci secondi. Riesci a vedere cosa c'è di sbagliato in questo codice, senza leggere la documentazione di Timeout
class?
Conclusione
-
null
esprime bene l'idea che il valore non sia qui. Non è fornito. Non disponibile. Non è né un numero, né una stringa zero / vuota o qualsiasi altra cosa. Non usarlo per i valori massimi o minimi.
-
int.MaxValue
è strongmente correlato alla lingua stessa. Non utilizzare int.MaxValue
per un limite di velocità massimo della classe Vehicle
o una velocità massima accettabile per un aeromobile, ecc.
-
Evita valori magici come -1
nel codice. Sono fuorvianti e portano a errori nel codice.
-
Crea la tua classe che sarebbe più semplice, con i valori minimi / massimi specificati. Ad esempio VehicleSpeed
può avere VehicleSpeed.MaxValue
.
-
Non seguire alcuna linea guida precedente e utilizzare i valori magici se è una convenzione generale per decenni in un campo molto specifico, utilizzato dalla maggior parte delle persone che scrivono codice in questo campo.
-
Non dimenticare di mischiare approcci. Ad esempio:
class DnsQuery
{
public const int NoTimeout = 0;
public int Timeout { get; set; }
}
this.query.Timeout = 0; // For people who are familiar with timeouts set to zero.
// or
this.query.Timeout = DnsQuery.NoTimeout; // For other people.
¹ Puoi creare il tuo tipo che include l'infinito. Qui, sto parlando solo del tipo int
nativo.