Req6: Better casting

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

 

IDEA: Casts should flow from left to right. Here are some candidate syntaxes:

Dim x1 = (HtmlPage.Document.GetElementsByTagName("a").First As HtmlElement).Children(0) As HtmlElement

Dim x2 = HtmlPage.Document.GetElementsByTagName("a").First.DirectCast(HtmlElement).Children(0).DirectCast(HtmlElement)

Dim x3 = HtmlPage.Document.GetElementsByTagName("a").First.CType(HtmlElement).Children(0).CType(HtmlElement)

Dim x4 = HtmlPage.Document.GetElementsByTagName("a").First.CTypeDynamic(HtmlElement).Children(0).CTypeDynamic(HtmlElement)

Dim x5 = HtmlPage.Document.GetElementsByTagName("a").First.Cast(HtmlElement).Children(0).Cast(HtmlElement)

The current code "y1" looks awkward because it doesn't flow from left to right (and likewise with C++ style casts "y2"):

    Dim y1 = DirectCast(DirectCast(HtmlPage.Document.GetElementsByTagName("a").First, HtmlElement).Children(0), HtmlElement)

Dim y2 = (HtmlElement)((HtmlElement)HtmlPage.Document.GetElementsByTagName("a").First).Children(0)

 

The "As" would mean the same as DirectCast. The "Cast()" operator mean... I'm not sure! It would be shorthand for DirectCast or CType or CTypeDynamic, but it's not obvious which!

 

IDEA:  Casts should use the type of their context to avoid typing. For example:

        Dim y = "1"

        Dim x As Integer = CType(y) ' infers CType(y, Integer) because of the context

 

 

 

Casting is more difficult than it appears. Eric Lippert wrote a great blog post on the C# casting operator. As an example the C# cast "(string)expr" does three opposite things:

  1. Sometimes "expr" has compile-time type Object, for example, but you know it's really a String, and you use a cast to tell this to the compiler. DirectCast and C# as do this and only this.
  2. Sometimes "expr" has compile-time type Char(), for example, and you're asking the compiler to find at compile-time conversion to turn it into a String. CType does this and the previous one.
  3. Sometimes "expr" has compile-time type Object, for example, and you don't know what it really is, but you're asking the runtime to look at the runtime type of "expr" and look for any user-defined conversions to that can turn it into a String. CTypeDynamic and the C# cast operator do this and the previous two.

 

Provisional evaluation from VB team: Flowing the casts from left to right is a decent idea. The fact that there are so many different meanings for casts make it difficult to use "As" or ".Cast()", but the other possibilities (.CType(), .DirectCast(), ...) look plausible. However, you can already do a pretty decent job with extension methods:

    <Extension()> Function [CType](Of T)(ByVal x As Object) As T

        Return CType(x, T)

    End Function

    Dim y = "1"

    Dim x = y.CType(Of Integer)()

 As for the idea of using context -- it doesn't improve readability. It would be better to just write "Dim x = CType(y,Integer)".