2013-01-31 17 views
6

Với đoạn mã sau:Loại dữ dội với nội tuyến nếu không thể làm việc cùng nhau?

Dim widthStr As String = Nothing 

này hoạt động - width được gán Nothing:

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

Nhưng điều này không - width trở thành 0.0 (mặc dù nó có vẻ là đang logic giống hệt nhau):

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

Tại sao? Tôi có thể làm gì để nó hoạt động không?

+0

bạn có thử tương tự trong C# không? 'double? width = widthStr! = null? Double.Parse (widthStr): (double?) Null; ' –

+0

hãy kiểm tra http://stackoverflow.com/questions/14633824/nullable-type-with-inline-if-cannot-work-together http: // stackoverflow. com/questions/2647558 ​​/ preserving-null-values-in-a-double-variable – spajce

+2

@HighCore - 'null' trong C# và' Nothing' trong VB.Net * không * tương đương. 'Nothing' là, khoảng,' default (T) '. –

Trả lời

4

Tất cả điều này đi xuống để phân tích loại biểu thức.

Nothing là một con thú kỳ diệu trong VB.Net. Nó xấp xỉ giống như default(T) trong C#.

Như vậy, khi cố gắng để xác định loại tốt nhất cho những điều sau đây:

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

Đối số thứ ba là loại Double. Đối số thứ hai có thể chuyển đổi thành Double (vì Nothing có thể trả lại giá trị mặc định của các loại giá trị). Như vậy, loại giá trị trả lại của If được xác định là Double.

Chỉ sau khi phân tích loại mẫu đó kết luận là bất kỳ sự chú ý nào được trả cho loại biến mà biểu thức này được gán. Và Double có thể được gán cho Double? mà không có bất kỳ cảnh báo nào.


Không có sạch cách để làm cho công việc biểu If() của bạn như thế nào bạn mong đợi. Bởi vì không có tương đương với null trong VB.Net. Bạn sẽ cần (ít nhất) để chèn DirectCast (hoặc tương đương) ở một bên hoặc một kết quả khác của số If để buộc phân tích loại xem Double? thay vì Double.

+0

+1, mặc dù tôi không nghĩ rằng tôi hoàn toàn hiểu câu trả lời của bạn. Bạn có gợi ý rằng nội tuyến 'If' là một hàm tổng quát dưới mui xe? Và đó là cách VS hoạt động để suy ra các loại cho nó? – Neolisk

+0

@Neolisk - Tôi đã chỉnh sửa câu hỏi của mình một vài lần kể từ lần đăng đầu tiên - bạn đã đọc phiên bản mới nhất chưa? 'If' không phải là một hàm tổng quát. Nhưng 'Không có gì' là, như tôi đã nói, một con thú ma thuật. Nó không có chữ (trong và của chính nó) và vì vậy bất kỳ thông tin kiểu nào khác được sử dụng trước tiên. –

+0

Thú vị, mặc dù tôi mong đợi phân tích kiểu để xem xét loại bên trái của phương trình. Dù sao, cảm ơn cho một lời giải thích kỹ lưỡng như vậy. – Neolisk

10

Tiếp tục đến câu trả lời của Damien, cách sạch để làm điều này là để không sử dụng Nothing, nhưng New Double? thay vì:

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

Và bây giờ mà kiểu của biểu thức If là đúng, điều này có thể được giảm đến:

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

+1. Cảm ơn bạn đã đề xuất. Tôi thường không thích sử dụng bất kỳ ký tự đặc biệt nào, để làm rõ mã. Vì vậy, 'Dim width As Nullable (Of Double) = Nếu (widthStr là không có gì, New Nullable (Of Double), CDbl (widthStr))' là thích hợp hơn. – Neolisk

+0

Tôi hiểu sở thích của bạn không sử dụng "ký tự đặc biệt" (tôi sẽ không sử dụng bất kỳ ký tự kiểu nào cho biến - nhưng tôi sẽ cho hằng số.) Nhưng trong trường hợp này IDE ném lỗi tham chiếu đến biểu mẫu '?' Cho 'Nullable (Of) '. –

+0

Bạn có nghĩa là mã của tôi sẽ không hoạt động? Nó làm việc cho tôi. – Neolisk