Si consideri il seguente codice:avviso del compilatore sbagliato quando si confrontano struct su null
DateTime t = DateTime.Today;
bool isGreater = t > null;
Con Visual Studio 2010 (C# 4, NET 4.0), ottengo il seguente avvertimento: CS0458
avvertimento : Il risultato dell'espressione è sempre 'null' di tipo 'bool?'
Questo non è corretto; il risultato è sempre false
(di tipo bool
):
Ora, il DateTime struct sovraccarica il (maggiore di) Operatore >
. Qualsiasi struttura non nullable (come DateTime) è implicitamente convertibile nel tipo Nullable<>
corrispondente. L'espressione sopra equivale esattamente a
bool isGreater = (DateTime?)t > (DateTime?)null;
che genera anche lo stesso avviso errato. Qui l'operatore >
è l'operatore sollevato. Funziona restituendo false se HasValue
di uno dei suoi due operandi è false
. In caso contrario, l'operatore sollevato sarebbe procedere a scartare i due operandi alla struct sottostante, e quindi chiamare il sovraccarico di >
definita da tale struct (ma questo non è necessario in questo caso in cui un operando non si HasValue
).
Puoi riprodurre il bug, ed è questo bug noto? Ho frainteso qualcosa?
Questo è lo stesso per tutti i tipi di struttura (tipi non semplici come int
e non tipi di enumerazione) che sovraccaricano l'operatore in questione.
(Ora, se usiamo ==
invece di >
, tutto dovrebbe essere del tutto simile (perché DateTime sovraccarica anche l'operatore ==
). Ma non è simile. Se dico
DateTime t = DateTime.Today;
bool isEqual = t == null;
ottengo non avvertimento ☹ a volte si vedono persone controllare accidentalmente una variabile o un parametro per nulla, non rendendosi conto che il tipo di loro variabile è una struttura (che sovraccarica ==
e che non è un tipo semplice come int
). sarebbe meglio se hanno avuto un avvertimento .)
Aggiornamento: con il compilatore C# 6.0 (basata su Roslyn) di Visual Studio 2015, il messaggio errato con isGreater
sopra si trasforma in un CS0464 con un messaggio di avviso corretto e disponibile. Inoltre, la mancanza di avviso con isEqual
sopra è fissa nel compilatore di VS2015, ma solo se si compila con /features:strict
.
'[nulla]> null non ha senso iniziare (almeno per me). Interessante comunque, penso che dovrebbe mettere in guardia sul 'bool' che finisce sempre come' false'. – Alex
Potrebbe essere utile: http://blogs.msdn.com/b/abhinaba/archive/2005/12/11/501544.aspx e http://blogs.msdn.com/b/abhinaba/archive/2005/12 /14/503533.aspx – Habib
È interessante notare che 'DateTime.CompareTo (oggetto)' _specifically_ restituisce '1' quando si confronta con' null', qualunque sia il tipo di oggetto passato. – Rawling