Freigeben über


Req2: null-propagating field access

[This post is part of a series, "wish-list for future versions of VB"]

 

IDEA: Introduce a syntax for null-propagating field access. We could use the syntax ".?" for this. For instance,

' What the user writes

Dim name = Customer.?Name

' The compiler translates it into this:

Dim $temp = Customer

Dim name = If($temp Is Nothing, Nothing, $temp.Name)

Incidentally, null-propagating already occurs in many parts of VB. For instance,

        Dim x As Integer? = Nothing

        Dim y = x + 5 ' "Nothing" propagates from "x" across + operator into "y"

        Dim xml = <xml><b>hello</b></xml>

        Dim p = xml...<a>

        Dim q = p.@href ' "Nothing" propagates from "p" across the .@ operator into "q"

 

Note that we have to be careful about concurrency when we do null-propagating field access. If we merely wrote "Dim name = If(Customer is Nothing, Nothing, Customer.Name)" then it's vulnerable if another thread sets Customer to Nothing after the test has passed but before we retrieved Customer.Name. That's why it's important to store Customer into $temp.

 

Provisional evaluation from VB team: This is cute, but doesn't seem worth adding new (cryptic) syntax to VB just to support this case.

Comments

  • Anonymous
    February 11, 2010
    If I remember it correctly there was proposal for VB 9 for "Nullable member lifting" without the cryptic syntax - just using ".". For some reasons it was finally not implemented, but I liked it. There are a few possible name collisions (Value, HasValue) but the syntax is nice. But it was only for Nullable. What about introducing some operator like "@(Customer.Name)" ? With increased use of LINQ we need a way of exception handling in expressions. PHP has something like this (http://www.php.net/manual/en/language.operators.errorcontrol.php). What about making some clever version of it - doing null propagation and also returning null when exception in inner expression occurs?

  • Anonymous
    February 15, 2010
    This would be nice to have (although I admit it’s not a huge issue now). I don’t think you could change the behaviour of the dot operator as it would break backwards compatibility, but you could use the dot question operator as you suggested, or even better just the question mark by itself? I like the syntax: Dim accountName As String = newCustomer?Account.Name it seems fairly ‘natural’, but I can appreciate that it may be way too difficult for the perceived return.

  • Anonymous
    February 18, 2010
    This has been already discussed before: http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx I think it would be cool to have, since it could reduce a lot of code writing, and at the same time, reduce the probability of unhandled exceptions.

  • Anonymous
    February 25, 2010
    Very useful! Easy to implement and many other laqnguages are currenctly adding this.

  • Anonymous
    February 25, 2010
    Actually, the @ operator falling back to the default value for the data type if there's any exception in evaluating exp in @exp is even more powerful! I like it very much. Please include.

  • Anonymous
    March 08, 2010
    I'm not sure I see the purpose.  You're still going to have to do a null check eventually, right?  I guess the idea is to avoid the endless null checks like: If customer IsNot Nothing Then    If customer.Name IsNot Nothing Then        If customer.Name.First IsNot Nothing Then etc. But I wonder if those couldn't be handled a better way, such as assertions or exceptions or code contracts.  Is it really OK for that many things to be null, or does it mean something went haywire somewhere?

  • Anonymous
    March 04, 2012
    That case would be great. The dollar sign however is ugly and very non "VBish" for my taste.