Ritenere:
Linguaggio,
Struttura,
Contesto.
1. Lingua
L'uso di ∞ può essere una soluzione per un massimo.
JavaScript, ad esempio, ha un infinito. C # non¹.
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, usare 2.147.483.647 non ha senso.
2. Quadro
.NET Framework è piuttosto incoerente su questo punto e il suo utilizzo di valori magici può essere criticato.
Ad esempio, "Hello".IndexOf("Z")
restituisce un valore magico -1
. E ' forse rende più facile (lo fa?) Per 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 no -123
? Un principiante può anche erroneamente pensare che 0
significhi anche "Non trovato" o semplicemente digitare male (position >= 0)
.
3. Contesto
Se il tuo codice è correlato a timeout nei socket di rete, utilizzare qualcosa che è stato usato da decenni per motivi di coerenza 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 capire:
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
è falso, cosa succede se imposto Duration
su 100?
Questo può portare a più errori. Immagina il seguente 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 dura dieci secondi. Riesci a vedere cosa c'è che non va in questo codice, senza leggere la documentazione della Timeout
classe?
Conclusione
null
esprime bene l'idea che il valore non sia qui. Non viene fornito. Non disponibile. Non è né un numero, né una stringa zero / vuota o qualsiasi altra cosa. Non utilizzarlo per valori massimi o minimi.
int.MaxValue
è fortemente correlato alla lingua stessa. Non utilizzare int.MaxValue
per un limite di velocità massima della Vehicle
classe o una velocità massima accettabile per un aeromobile, ecc.
Evita valori magici come -1
nel tuo codice. Sono fuorvianti e portano a errori nel codice.
Crea la tua classe che sarebbe più semplice, con i valori minimo / massimo specificati. Ad esempio VehicleSpeed
può avere VehicleSpeed.MaxValue
.
Non seguire alcuna linea guida precedente e utilizzare valori magici se si tratta di 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 mescolare gli approcci. Per 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.
¹ È possibile creare il proprio tipo che include l'infinito. Qui, sto parlando int
solo di tipo nativo .