2012-02-29 9 views
19

Qualcuno ha informazioni concrete su come C# gestisce i confronti con i tipi Nullable<T> quando un lato del confronto è nullo?In che modo i tipi nullable gestiscono valori nulli con operatori di confronto?

Come ho capito dalla sperimentazione con il compilatore, sembra che il confronto restituisca sempre false, ma non riesco a trovare alcuna documentazione per eseguire il backup. Si tratta di una vera caratteristica del linguaggio (e quindi qualcosa su cui posso contare), o si tratta di un dettaglio di implementazione che potrebbe cambiare nelle versioni future?

In altre parole, il seguente metodo restituisce true implica y.HasValue e puoi indicarmi la documentazione che dimostra che lo fa?

public bool foo(int x, int? y) 
    { 
     return x < y; 
    } 
+1

Perché dovresti aspettarti che * mai * si confronti uguale a * qualsiasi * valore? –

risposta

43

Qualcuno ha informazioni concrete su come C# gestisce il confronto con i tipi Nullable quando una parte del confronto è nullo?

Sì - la specifica del linguaggio C#, sezione 7.3.7. In questo caso, si tratta di un operatore relazionale:

Per gli operatori relazione < > <= >= una forma alzato di un operatore esiste se i tipi operandi sono entrambi i tipi non annullabili e se il tipo di risultato è bool. La forma sollevata viene creata aggiungendo un singolo modificatore ? a ciascun tipo di operando. L'operatore sollevato produce il valore false se uno o entrambi gli operandi sono nulli. In caso contrario, l'operatore sollevato disegna gli operandi e applica l'operatore sottostante per produrre il risultato bool.

Ci sono sezioni analogamente dettagliate per altri operatori.

In caso di dubbi su come funzionano alcuni aspetti della lingua (e se è garantita o specifica per l'implementazione), le specifiche del linguaggio C# dovrebbero essere il primo punto di riferimento.

+3

Per scaricare le specifiche per la lettura: http://www.microsoft.com/download/en/details.aspx?id=7029 –

+0

Questa parte della sezione 4.1.10 delle specifiche mi ha aiutato anche a capire tutto questo: "Le conversioni implicite sono disponibile [...] da T a T ?. " – andrej351

+0

Jon, questo potrebbe essere un campo lungo, ma ti capita di sapere *** perché ***, per gli '<=' and '> =' operatori, "* L'operatore sollevato produce il valore' false' se uno o entrambi gli operandi sono ' null' * "? Mi sembra strano '(null == null) == true', tuttavia' (null <= null) == false'. –

5

Se uno dei valori è null, il confronto sarà falsa (ad eccezione di !=)

Quando si esegue il confronto con i tipi nullable, se il valore di uno dei tipi nullable è null e l'altro no, tutti i confronti valutano su false tranne per! = (non uguale). È importante non per assumere che, poiché un confronto particolare restituisce false, il caso opposto restituisce true. Nell'esempio seguente, 10 non è maggiore di, minore di, né uguale a null. Solo num1! = Num2 restituisce true.

MSDN Source

+0

Non so se i risultati sono diversi. Tuttavia, questa citazione riguarda il confronto tra due tipi di Nullable. – Joe

2

MSDN ha il seguente da dire sulla questione:

Quando si esegue il confronto con i tipi nullable, se il valore di uno dei tipi nullable è nullo e l'altro non è, tutti i confronti valutare a false tranne per! = (non uguale)."

http://msdn.microsoft.com/en-us/library/2cf62fcy(v=vs.100).aspx

Ecco gli esempi di codice forniti:

int? num1 = 10; 
int? num2 = null; 
if (num1 >= num2) 
{ 
    Console.WriteLine("num1 is greater than or equal to num2"); 
} 
else 
{ 
    // This clause is selected, but num1 is not less than num2. 
    Console.WriteLine("num1 >= num2 returned false (but num1 < num2 also is false)"); 
} 

if (num1 < num2) 
{ 
    Console.WriteLine("num1 is less than num2"); 
} 
else 
{ 
    // The else clause is selected again, but num1 is not greater than 
    // or equal to num2. 
    Console.WriteLine("num1 < num2 returned false (but num1 >= num2 also is false)"); 
} 
if (num1 != num2) 
{ 
    // This comparison is true, num1 and num2 are not equal. 
    Console.WriteLine("Finally, num1 != num2 returns true!"); 
} 
// Change the value of num1, so that both num1 and num2 are null. 
num1 = null; 
if (num1 == num2) 
{ 
    // The equality comparison returns true when both operands are null. 
    Console.WriteLine("num1 == num2 returns true when the value of each is null"); 
} 
0

Se non c'è un CompareTo specifica implementata, quindi la mia ricerca mi dice che l'oggetto utilizzerà il CompareTo (oggetto Nel caso di un int, è possibile confrontare un oggetto int o un oggetto, in questo caso controlla solo se l'oggetto è nullo o no. Ecco un collegamento al comparatore int (oggetto), dettagli il motivo dei risultati del confronto tra int e un oggetto

http://msdn.microsoft.com/en-us/library/system.int32.aspx

non riesco a trovare nulla di certo, ma io non vedo nulla che indichi che il .NET framework è stato esteso per includere un metodo per la CompareTo System.Nullable<T> per ogni <T>.

Se fosse il mio codice, mi proteggerei ed estenderei la classe Int per includere un CompareTo.

0

So di essere in ritardo, ma mi butto i miei due centesimi in

Se la memoria non serve, le regole per un operatore di confronto sono i seguenti:.

  • Se x ed y sono nulli , restituisce 0 (sono uguali).
  • Se x è nullo e y non lo è, restituisce -1 (x è minore di y).
  • Se x non è nullo e y è nullo, restituisce 1 (x è maggiore di y).

Per tutti i valori non nulli:

  • Quando il valore di x restituisce meno di y, ritorno -1.
  • Quando il valore di x restituisce y, ritorno 0.
  • Quando il valore di x restituisce maggiore di y, ritorno 1.

Per tutti gli effetti, un Nullable <T> restituisce null quando non ha alcun valore. Quindi le regole sono essenzialmente le stesse. Almeno, è così che ho scritto i miei paragoni. Se sto sbagliando, allora, santo dio, sto sbagliando, e spero davvero che qualcuno mi dica come aggiustarlo !!

Problemi correlati