2013-01-31 10 views
6

Dato il seguente codice:Tipo nullable con inline se non può funzionare insieme?

Dim widthStr As String = Nothing 

Questo funziona - width viene assegnata Nothing:

Dim width As Nullable(Of Double) 
If widthStr Is Nothing Then 
    width = Nothing 
Else 
    width = CDbl(widthStr) 
End If 

ma questo non significa - width diventa 0.0 (anche se sembra essere il codice logicamente identici):

Dim width As Nullable(Of Double) = If(widthStr Is Nothing, Nothing, CDbl(widthStr)) 

Perché? C'è qualcosa che posso fare per farlo funzionare?

+0

hai provato lo stesso in C#? 'Raddoppiare? width = widthStr! = null? Double.Parse (widthStr): (double?) Null; ' –

+0

controlla http://stackoverflow.com/questions/14633824/nullable-type-with-inline-if-cannot-work-together http: // stackoverflow. it/questions/2647558 ​​/ preserving-null-values-in-a-double-variable – spajce

+2

@HighCore - 'null' in C# e' Nothing' in VB.Net sono * non * equivalenti. 'Nothing' è, approssimativamente,' default (T) '. –

risposta

4

Tutto questo si riduce a digitare l'analisi delle espressioni.

Nothing è una bestia magica in VB.Net. È approssimativamente lo stesso di default(T) in C#.

Come tale, quando si cerca di determinare il tipo migliore per il seguente:

If(widthStr Is Nothing, Nothing, CDbl(widthStr)) 

Il terzo argomento è di tipo Double. Il secondo argomento è convertibile in Double (poiché Nothing può restituire il valore predefinito dei tipi di valori). Di conseguenza, il tipo del valore restituito di If è determinato come Double.

Solo dopo che il pezzo di analisi del tipo ha concluso è un'attenzione dedicata al tipo di variabile a cui viene assegnata questa espressione. E Double è assegnabile a Double? senza alcun avviso.


Non c'è pulito modo per rendere il vostro lavoro If() espressione come vi aspettavate. Perché non c'è equivalente a null in VB.Net. Avresti bisogno (almeno) di inserire un DirectCast (o equivalente) su un lato o su un altro dei potenziali risultati del If per forzare l'analisi del tipo a vedere Double? anziché Double.

+0

+1, anche se non penso di capire completamente la tua risposta. Stai suggerendo che un tale inline 'If' è una funzione generica sotto il cofano? Ed è così che VS lavora per inferirne i tipi? – Neolisk

+0

@Neolisk - Ho modificato la mia domanda alcune volte dal primo post - hai letto la versione più recente? 'If' non è una funzione generica. Ma "Niente" è, come ho detto, una bestia magica. È senza nome (di per sé) e quindi vengono usate prima tutte le altre informazioni di tipo. –

+0

Interessante, sebbene mi aspetto che l'analisi del tipo consideri il tipo del lato sinistro dell'equazione. Comunque, grazie per una spiegazione così approfondita. – Neolisk

10

seguito alla risposta di Damien, il modo pulito per farlo è quello di non uso Nothing, ma New Double? invece:

Dim width As Double? = If(widthStr Is Nothing, New Double?, CDbl(widthStr)) 

E ora che il tipo di If espressione è corretta, questo potrebbe essere ridotta a:

Dim width = If(widthStr Is Nothing, New Double?, CDbl(widthStr)) 
+0

+1. Grazie per un suggerimento. Generalmente preferisco non usare nessuno dei caratteri speciali, per chiarezza del codice. Quindi 'Dim width As Nullable (Of Double) = If (widthStr Is Nothing, New Nullable (Of Double), CDbl (widthStr))' è più preferibile. – Neolisk

+0

Capisco che preferisci non usare "caratteri speciali" (non userei caratteri di qualsiasi tipo per variabili - ma lo farò per le costanti.) Ma in questo caso l'IDE lancia errori riferendosi al modulo '' 'per' Nullable (Of) '. –

+0

Vuoi dire che il mio codice non funzionerebbe? Funziona per me. – Neolisk