In primo luogo: non fare troppo in una singola istruzione. Se hai un numero enorme di operazioni di dereferenziamento in una riga, sarà molto più difficile trovare il colpevole. Il Law of Demeter aiuta anche con questo - se hai qualcosa come order.SalesClerk.Manager.Address.Street.Length
allora hai un sacco di opzioni da guadare quando ottieni un'eccezione. (Sono non dogmatica circa la Legge di Demetra, ma tutto con moderazione ...)
In secondo luogo: preferisco fusione rispetto all'uso di as
, a meno che sia valida per l'oggetto sia un tipo diverso, che normalmente comporta un controllo nulla immediatamente dopo. Così qui:
// What if foo is actually a Control, but we expect it to be String?
string text = foo as string;
// Several lines later
int length = text.Length; // Bang!
Qui ci saremmo un NullReferenceException e, infine, risalire al text
essere nulla - ma poi non si sa se è perché foo
era nullo, o perché era un tipo di inaspettato. Se dovesse davvero, davvero essere un string
, poi gettato invece:
string text = (string) foo;
Ora sarete in grado di capire la differenza tra i due scenari.
In terzo luogo: come altri hanno già detto, convalidare i dati, in genere argomenti per API pubbliche e potenzialmente interne. Lo faccio in un numero sufficiente di posti in Noda Time che ho una classe di utilità per aiutarmi a decodificare il controllo. Così, per esempio (da Period
):
internal LocalInstant AddTo(LocalInstant localInstant,
CalendarSystem calendar, int scalar)
{
Preconditions.CheckNotNull(calendar, "calendar");
...
}
Si dovrebbe documento ciò che può e non può essere nullo, anche.
fonte
2012-04-12 16:57:51
Sempre "Asserire" liberamente per valori nulli. – leppie
@leppie - questo è un sacco di affermazione! Sì, potevo farlo ma speravo in una soluzione più elegante per tenere conto di situazioni come me che mi dimentico di farlo :) –
Protip: tieni i metodi piccoli (diciamo al massimo 10-20 linee), quindi non hai davvero bisogno dei numeri di riga . – leppie