strano comportamento del '??' - operatore in C # 3.5
-
26-10-2019 - |
Domanda
Questo è un bug o sto interpretando il '??' - operatore che non va? Controllare la proprietà get qui sotto e commenti.
sto usando C # .NET 3.5
private List<MyType> _myTypeList;
private List<MyType> MyTypeList
{
get
{
//The two code lines below should each behave as the three under, but they don't?
//The ones uncommented are working, the commented result in my list always returning empty (newly created I suppose).
//return _myTypeList ?? new List<MyType>();
//return _myTypeList == null ? new List<MyType>() : _myTypeList;
if (_myTypeList == null)
_myTypeList = new List<MyType>();
return _myTypeList;
}
}
EDIT:. Siamo spiacenti per tutti coloro che guardava la questione quando è stato appena chiesto, lì dove alcuni errori in esso che ricevuti confondere tutti
Grazie per tutte le grandi e veloci feedback! Ora ho capito l'errore che ho fatto. Grazie!
Soluzione
Questa riga:
return _myTypeList == null ? new List<MyType>() : _myTypeList;
è equivalente a:
if (_myTypeList == null)
return new List<MyType>();
return _myTypeList;
Per non:
if (_myTypeList == null)
_myTypeList = new List<MyType>();
return _myTypeList;
La versione con ??
, cui è stato aggiunto in seguito, è così illeggibile che non voglio analizzarlo. Andiamo ?
prima a destra.
Altri suggerimenti
Se è necessario utilizzare l'uso ??
piace
_myTypeList = _myTypeList ?? new List<MyType>();
return _myTypeList;
, ma un semplice, se va bene così
Quando si utilizza la sintassi
return _myTypeList == null ? new List<MyType>() : _myTypeList;
se _myTypeList è nullo poi si torna un nuovo MyType elenco di tipo List (). _myTypeList tuttavia rimane nullo. Non si inizializza.
Mentre nel secondo caso, in realtà si inizializza _myTypeList e poi restituirlo.
Versione A:
return _myTypeList ?? (_myTypeList = new List<MyType>());
Versione B:
return _myTypeList == null ? new List<MyType>() : _myTypeList;
Versione C:
if (_myTypeList == null)
_myTypeList = new List<MyType>();
return _myTypeList;
A e C dovrebbero comportarsi allo stesso. B non dovrebbe - non imposta _myTypeList
ad una nuova lista, restituisce una sola. È possibile utilizzare la stessa sintassi si utilizza in versione A per renderlo equivalente:
return _myTypeList == null ? _myTypeList = new List<MyType>() : _myTypeList;
Il mezzo operatore ??
: Se la mano sinistra operando non è null
, il risultato dell'operazione è l'operando mano sinistra. In caso contrario, il risultato dell'operazione è l'operando di destra. Cioè:.
foo = bar ?? frob
foo = bar
Poi, se bar != null
, in caso contrario, foo = frob
.
Il codice si sta dimostrando, non usa l'?? operatore (operatore fondono). Invece, si sta utilizzando l'operatore ternario.
Prova
return _myTypeList ?? ( _myTypeList = new List<MyType>() );
, invece.
Check this out:
static void Main( string[] args )
{
var x = GetList ();
if( _theList == null )
{
Console.WriteLine ("_theList is null");
}
else
{
Console.WriteLine ("_theList has been initialized.");
}
Console.ReadLine ();
}
private static List<int> _theList;
public static List<int> GetList()
{
return _theList ?? ( _theList = new List<int> () );
}
Il seguente output '_theList è stata inizializzata'.
La linea ha commentato:
//return _myTypeList == null ? new List<MyType>() : _myTypeList;
non potrà mai funzionare come previsto, dal momento che non sei (pigro) inizializzazione ovunque _myTypeList.
_myTypeList == nul
l sarà sempre valutata come vera, dal momento che non è mai _mytypeList inizializzato, e, quindi, si sarà sempre restituire una nuova istanza List.