VB.NET: risultati inaspettati nell'uso di "IF" come operatore ternario...

lunedì 22 giugno 2009 - 14.28

valter.mi Profilo | Newbie

Sto rilevando un problema nell'uso di "IF" come operatore ternario in VB.NET.
Esempio:
Dim numero As Nullable(Of Decimal)
Dim zero As Decimal

If True Then
numero = Nothing
Else
numero = (10 / zero)
End If

a questo punto "numero" continua a valere "Nothing" .
In base alle specifiche d'uso di "IF come operatore ternario dovrei aspettarmi lo stesso risultato con la seguente espressione:
numero = If(True, Nothing, (10 / zero))
ma in realtà alla variabile "numero" viene assegnato il valore "0".

Qualcuno è in grado di spiegarmi tale comportamente apparentemente anomalo?
Grazie

Jeremy Profilo | Guru

If True Cosa??? ... cosa deve essere true per impostare numero a Nothing????
In questo modo sarà sempre True la condizione.
Forse volevi scrivere(anche se non ne capisco il senso):

If zero>0 Then numero = (10 / zero) Else numero = Nothing End If

Facci sapere...
Ciao

mi.valter Profilo | Newbie

Mi spiace se il post ti è sembrato un po' criptico. Ho fatto solo degli esempi e mi sono concentrato sul problema centrale che avevo enunciato.

Comunque ho capito che il problema è dato dal compilatore che interpreta i valori restituiti in modo poco intuibile a partire dai tipi definiti per i due argomenti(vedi http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=341263).

Provo a spiegarmi meglio.
Nel processo di conversione di un progetto da VB6 a VB.NET ho utilizzato "IF" come operatore ternario per snellire alcune parti di codice utilizzando la "short-circuit evaluation" e mi sono imbattuto in risultati inaspettati. In particolare, avevo la necessità che, in alcuni casi, venisse restituito "Nothing" per assegnarlo ad un tipo dichiarato Nullable.

Ora farò solo degli esempi generici per evidenziare questi comportamenti, per lo meno, poco intuibili.
Questo è il contesto:
- utilizzo di VB.NET 2008 con "Option Strict Off" che permette i cast impliciti
- utilizzo di "IF" come operatore ternario al posto del classico IF..THEN..ELSE (vedi http://msdn.microsoft.com/en-us/library/bb513985.aspx)
- utilizzo di tipi Nullable
- restituzione di valore Nothing

Dim dtNull As Nullable(Of Date)
Dim dtNull2 As Nullable(Of Date)
Dim st As String
Dim st2 As String
Dim dt As Date
Dim dt2 As Date = Today
Dim num As Decimal = 10
Dim numNull As Nullable(Of Decimal)
Dim numNull2 As Nullable(Of Decimal)

'Esempi con variabile che riceve l'assegnazione di tipo "String"
-----------------------------------------------------------------
st = If(True, Nothing, st2) 'Restituisce correttamente "Nothing"
st2 = ""
st = If(True, Nothing, st2) 'Restituisce correttamente "Nothing"
st = If(True, Nothing, "Prova") 'Restituisce correttamente "Nothing"
st = If(True, Nothing, 0) 'Restituisce "0"
st = If(True, Nothing, num) 'Restituisce "0"
st = If(True, Nothing, dtNull2) 'Compila ma va in errore: "L'oggetto nullable deve avere un valore."


'Esempi con variabile che riceve l'assegnazione di tipo "Date?"
-----------------------------------------------------------------
dtNull = If(True, Nothing, st) 'Compila ma va in errore: "Cast non valido dalla stringa "" al tipo 'Date'."

st = ""
dtNull = If(True, Nothing, st) 'Compila ma va in errore: "Cast non valido dalla stringa "" al tipo 'Date'."

st = "Prova"
dtNull = If(True, Nothing, st) 'Compila ma va in errore: "Cast non valido dalla stringa "" al tipo 'Date'."

dtNull = If(True, Nothing, "Prova") 'Restituisce correttamente "Nothing" <<<<<<

dtNull = If(True, Nothing, num) 'Non compila e da questo errore: "Impossibile convertire il valore di tipo 'Decimal' in 'Date?"
dtNull = If(True, Nothing, numNull) 'Non compila e da questo errore: "Impossibile convertire il valore di tipo 'Decimal?' in 'Date?"
dtNull = If(True, Nothing, 10) 'Non compila e da questo errore: "Impossibile convertire il valore di tipo 'Integer' in 'Date?"

dtNull = If(True, Nothing, dt) 'Restituisce il valore di default del tipo "Date" cioè #12:00:00 AM#
dtNull = If(True, Nothing, dt2) 'Restituisce il valore di default del tipo "Date" cioè #12:00:00 AM#

dtNull = If(True, dtNull2, dt) 'Restituisce correttamente "Nothing"
dtNull = If(True, Nothing, dtNull2) 'Restituisce correttamente "Nothing"


'Esempi con variabile che riceve l'assegnazione di tipo "Decimal?"
-----------------------------------------------------------------
numNull = If(True, Nothing, "") 'Restituisce "0"

st = ""
numNull = If(True, Nothing, st) 'Restituisce "0"

st = "Test"
numNull = If(True, Nothing, st) 'Restituisce "0"

numNull = If(True, numNull2, num) 'Restituisce correttamente "Nothing"
numNull = If(True, Nothing, numNull2) 'Restituisce correttamente "Nothing"


Conclusioni:
Come ormai ho capito da tempo, tutte le conversioni IMPLICETE in VB:NET sono fonte di confusione e possibili risultati inattesi.

Grazie per la pazienza.

Ciao

Jeremy Profilo | Guru

Ciao Valter.
Attento a non creare un nuovo utente ad ogni post che inserisci!!!

Se ho capito bene, la tua è una sfida con il compilatore .... bhe! Chi la dura la vince!!!
Ma ti posso assicurare che vince sempre lui.

Ciao
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5