2009-09-20 14 views

risposta

20

È una vecchia abitudine evitare l'errore accidentale di myVar = null (whoops). È ancora utile in alcune lingue, ma C# ti proteggerà dal farlo, quindi non è necessario lì.

+0

@devoured sì - solo quello. –

+0

Inoltre, è un'abitudine generale di dire "someConst == myVar", dove someConst sembra essere nullo in questo caso. Alcuni linguaggi di scripting possono tradurre quanto sopra come "someConst.equals (myVar)", e se lo fai al contrario, potresti ottenere un NPE. Correzione – Bugmaster

+0

: C# non ti consente di farlo. – Noldorin

8

Si tratta di un residuo C dove compilatori più anziani non avrebbero prendere questo:

if (foo = null) 

quando si intende questo:

if (foo == null) 

L'esempio scherzo classico è questo errore:

if (fireTheNukes = true) 
    fireTheNukes(); 

Questo è generalmente accettato come un pattern arcaico come qualsiasi compilatore che ne valga la pena. una dichiarazione condizionale. Eviterei questo schema nel codice in quanto non serve a nulla in questi giorni.

+0

@Andrew: Ho pensato che se (foo = null) fosse un'affermazione perfettamente valida (assegna il valore a foo e poi controlla se è vero). Non pensavo che avesse nulla a che fare con i compilatori, non "catturandolo". –

+0

@Esteban - che lingua e compilatore?Mentre il compilatore C# _will_ consente un assegnamento booleano in un'istruzione condizionale genererà anche un "hai davvero intenzione di farlo?" avvertimento. –

2

È una vecchia abitudine difensiva. Se metti la costante a sinistra, dimenticando il secondo segno di uguale risulta un errore di compilazione. Nel formato più normale, dimenticare che il secondo segno di uguale risulta nell'assegnazione di null alla variabile.

In altre parole,

myVar = null 

è dannoso e sorprendente, mentre

null = myVar 

viene catturato dal compilatore.

2

È un'abitudine dei programmatori C, uno che è stato portato in C# in questo caso, ma in realtà non è necessario.

Considerare in C che se si digita accidentalmente if (myVar = null), il compilatore eseguirà il compito e non si lamenterà. La commutazione dell'ordine di myVar e null assicura che venga generato un errore del compilatore se == viene erroneamente digitato in errore come =. C#, tuttavia, genera un avvertimento del compilatore in entrambi i casi, quindi questa stranezza non è necessaria.

2

Viene da C/C++ per la cattura lasciando fuori un segno di uguale:

myVar = null 

Ma non è necessaria in C#.

1

Come altri hanno menzionato, è una tattica difensiva contro i problemi che possono derivare dal fatto che in C e alcuni derivati ​​C (incluso C#) un'espressione di assegnazione valuta il valore di tale incarico.Questo è ciò che permette di fare:

if (a = true) { /* This will always get done, as "a = true" evals to true */ } 

e

int a = b = c = d = 10; 

Come assegnazione è associativa a destra questo è effettivamente

int a = (b = (c = (d = 10))); 

dove ogni espressione all'interno di una coppia tutore valuterà al valore del compito, che in questo caso 10 e a, b, c e d saranno quindi tutti 10.

Per evitare potenziali errori - mescolando gli operatori di assegnazione e di uguaglianza - alcuni programmatori preferiscono posizionare sempre la costante a sinistra, come se l'operatore di assegnazione venisse usato accidentalmente, il compilatore si lamenterebbe che non è possibile assegnare a una costante.

Questo è, tuttavia, meno di un problema in C# per due motivi. In primo luogo, a differenza di C, C# non consente che i valori arbitrari vengano interpretati come valori booleani.

Questo era necessario in C poiché non aveva un vero tipo booleano, si basava semplicemente sull'interpretazione di altri valori come numeri interi (dove 0 è falso e non zero è vero) o puntatori (dove NULL è falso). Questo significava che si poteva poi fare qualcosa di simile

if (10) { /* This will always get done */ } 
if (0) { /* This will never get done */ } 
if (p) { /* This will get done is p is not null */ } 
if (NULL) { /* This will never get done */ } 

Tuttavia, poiché C# non consente espressioni arbitrarie di essere interpretati come un valore booleano questi non funzioneranno in C#. Significa anche che

if (a = 10) { } 

non si compila in C#, come l'espressione "a = 10" restituisce il valore dell'espressione, 10, che non può quindi essere interpretata come il valore booleano richiesto.

La seconda ragione per cui è meno di un problema è che nella percentuale, ora molto più piccola, di casi in cui il risultato del compito può essere interpretato come un valore booleano il compilatore emette un avvertimento per assicurarsi che tu l'abbia davvero significato fare quello.

L'avvertimento può essere disattivato con

#pragma warning disable 665 

Tuttavia, la presenza di tale codice è spesso un odore di codice cattivo e probabilmente è meglio trattati dal refactoring per rendere il codice più chiaro.

Problemi correlati