2013-01-31 12 views
6

Biorąc pod uwagę następujący kod:Typ nullable z wbudowanym, jeśli nie może działać razem?

Dim widthStr As String = Nothing 

To działa - width przypisany Nothing:

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

Ale tego nie robi - width staje 0.0 (choć wydaje się być logicznie identyczny kod):

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

Dlaczego? Czy jest coś, co mogę zrobić, żeby to zadziałało?

+0

czy próbowałeś tego samego w C#? 'podwójne? width = widthStr! = null? Double.Parse (widthStr): (double?) Null; ' –

+0

proszę sprawdzić http://stackoverflow.com/questions/14633824/nullable-type-with-inline-if-cannot-work-together http: // stackoverflow. com/questions/2647558 ​​/ zachowując-wartości-null-w-podwójnej zmiennej – spajce

+2

@HighCore - 'null' w C# i' Nothing' w VB.Net są * nie * równoważne. 'Nothing' to, w przybliżeniu,' default (T) '. –

Odpowiedz

4

Wszystko to sprowadza się do analizy typów wyrażeń.

Nothing to magiczna bestia w VB.Net. Jest mniej więcej taki sam jak default(T) w języku C#.

Jako takie, gdy próbuje ustalić najlepszy typ za:

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

Trzeci argument jest typu Double. Drugi argument można przekształcić na Double (ponieważ Nothing może zwrócić domyślną wartość typów wartości). Jako taki, typ wartości zwracanej If jest określony jako Double.

Jedynie po, że analiza typu zakończyła się, należy zwrócić uwagę na typ zmiennej, do której przypisane jest to wyrażenie. I Double można przypisać do Double? bez ostrzeżeń.


Nie ma czysty sposób, aby swoją pracę ekspresji If() jak oczekiwano. Ponieważ nie ma odpowiednika null w VB.Net. Potrzebujesz (przynajmniej) wstawić DirectCast (lub odpowiednik) na jednej stronie lub na innym potencjale wyników If, aby wymusić analizę typu, aby zobaczyć Double? zamiast Double?.

+0

+1, chociaż nie sądzę, że rozumiem twoją odpowiedź. Sugerujesz, że takie wbudowane 'If' jest funkcją generyczną pod maską? I tak działa VS, aby wnioskować o tym typy? – Neolisk

+0

@Neolisk - Kilka razy zmieniłem moje pytanie od pierwszego opublikowania - czy przeczytałeś najnowszą wersję? 'If' nie jest funkcją ogólną. Ale "Nic" to, jak już powiedziałem, magiczna bestia. Jest bez typów (sam w sobie) i dlatego wszelkie inne informacje o typach są używane jako pierwsze. –

+0

Interesujące, chociaż spodziewałbym się, że analiza typu uwzględni typ lewej strony równania. W każdym razie, dzięki za tak dokładne wyjaśnienie. – Neolisk

10

nawiązaniu do odpowiedzi Damiana, czyste sposobem, aby to zrobić, to nie użytku Nothing, ale New Double? zamiast:

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

A teraz, rodzaj ekspresji If jest prawidłowa, to może być zmniejszona do:

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

+1. Dzięki za sugestię. Generalnie wolę nie używać żadnego ze znaków specjalnych, aby uzyskać klarowność kodu. Tak więc 'Dim width As Nullable (Of Double) = If (widthStr Is Nothing, New Nullable (Of Double), CDbl (widthStr))' jest bardziej preferowane. – Neolisk

+0

Rozumiem twoje preferencje, aby nie używać "znaków specjalnych" (nie używałbym żadnych znaków typu dla zmiennych - ale będę dla stałych), ale w tym przypadku IDE zgłasza błędy odnoszące się do '' 'formularza dla' Nullable (Of) '. –

+0

Czy masz na myśli mój kod nie działa? To działa dla mnie. – Neolisk

Powiązane problemy