Mads Torgersen recently gave a talk called “The Future of C#”, where he described some potential C# ideas that are on the minds of the team at Microsoft. He showed glimpses of a delightful IDE experience that deeply understands your code and that helps with diagnostics and refactorings. On the language front, he showed no big language paradigm shifts, but instead various places where C# could remove some irksome limitations and increase productivity.

 

What would be the VB equivalents of what he showed?

 

Here are some ideas. Please note that, as with what Mads said in his talk, nothing in the list of language ideas is committed. This is all just speculation about potential ideas for some future version of VB. Some of these ideas follow in spirit (i.e. removing VB-specific irksome limitations). Others are ideas that follow in detail (i.e. speculations about the VB equivalent of C# ideas that Mads mentioned). There are many other ideas that we've considered in the past, some of which have made it into the product eventually, some of which are still under consideration even if not on this list, and some of which were rejected.

As always, the best place to tell us what features you'd like to see is through voting on UserVoice. If there are bugs you want us to fix, file them on Connect. If you want to be part of a public discussion on language design issues, you can do that anywhere - we read your comments on our blog posts, and we read your blogs and tweets (especially if you point us to them!)

 

Comments after implicit line-continuations

Currently you can’t write comments after an implicit line-continuation. This is a pain, especially when you want to comment individual lines in a LINQ expression or an array/object initializer. IDEA: Allow comments after implicit line-continuations.

Dim  invites = { "Jim" ,    ' got to invite him! 
                "Marcy" ,  ' Jim's wife 
                "Jones" } 

Dim  addrs =  From  i  In  invites      ' go through list 
             Let  addr = Lookup(i)   ' look it up 
             Select  i, addr 

 

 

Readonly autoprops

Currently when you write an auto-property, it is always ReadWrite. IDEA: (1) let you declare ReadOnly auto-properties, and the compiler will implicitly generated a ReadOnly backing field; (2) let you assign to a ReadOnly auto-property within the constructor, and the compiler will implicitly treat it as a write to the backing field.

Class  Customer 

     ReadOnly Property  Name  As  String 

     ReadOnly Property  Address  As  String 

     ReadOnly Property  LastModified  As  DateTime  =  DateTime .Now 

  

     Sub  New (name  As  String , address  As  String ) 

         Me .Name = name 

         Me .Address = address 

     End  Sub 

End  Class 

  

  

  

Multiline strings

Currently in VB, string literals can’t be split over multiple lines. IDEA: let them, as is currently the case in C# verbatim string.

Dim  x =  < xml ><![CDATA[ this is how 
I currently write a multiline string ]]></ xml > .Value 

  

Dim  y =  "this is how
I'd like to write a multiline string"
 

  

 

String Interpolation

Currently when you use String.Format with a lot of arguments, it’s easy to get your {0}, {1}, {2}, … mixed up. And when you build up a string using concatenation it can get hard to read. IDEA: Allow string interpolation, which is found in various other languages. The code below shows an idea for syntax - use the prefix $ in front of an interpolated string, and interpolate an expression within curly braces, and allow format specifiers. And it shows an idea for semantics - translate it into String.Format in InvariantCulture, but let the compiler optimize into String.Concat or whatever it wants if that’s faster.

Dim  query =  $"http://{ url }?name={ Escape(name) }&id={ Escape(id) }&o=xml"

' = String.Format("http://{0}?name={1}&id={2}&o=xml",
'                 url, Escape(name), Escape(id),
'                 CultureInfo.InvariantCulture)
 

Dim  fn =  $"{ drive }:\{ folder }\{ name }.{ ext }"

' = String.Format("{0}:\{1}\{2}.{3}",
'                 drive, folder, name, ext,
'                 CultureInfo.InvariantCulture)


Dim  csv =  $"Name,FractionIn,FractionOut
{
 Code1.Name },{ Code1.FIn :0.00},{ Code1.FOut :0.00}"

' = String.Format("Name,FractionIn,FractionOut{0}{1},{2:0.00},{3:0.00}",
'                 vbCrLf, Code1.Name, Code1.FIn, Code1.FOut,
'                 CultureInfo.InvariantCulture)
 

  

  

Ease up on LINQ expression names

Currently when you write a Select clause, then under the hood VB creates an anonymous type and tries to pick names for the members. In the code below it picks the name “ToString” – but this isn’t allowed as a member name, and so it gives an error! IDEA: if “Select” is the last clause, and has only one item, then skip name-generation entirely. (Also do this if it’s followed only by Distinct / Skip / Take).

Dim  args  As  String () 

Dim  q =  From  arg  In  args 

         Select  arg.ToString()
' BC36606: Range variable name cannot match the
' name of a member of the 'Object' class 
 

 

International date literals

Currently in VB we can only write date literals in US format. IDEA: allow them to be written in international (ISO) format as well. (Updated thanks to @rbirkby's comment that ISO requires 2-digit months and days):

Dim  us_format  = #2/3/2013 17:52:51#
Dim  iso_format = #2013-02-03 17:52:51# 

 

 

Binary Literals

Currently other languages such as F#, Java and some versions of C++ allow binary literals while VB only offers decimal, octal and hexadecimal. IDEA: allow binary literals, with the &B prefix:

Dim  code = &B001010 

 

 

Digit Group Separators

If you had to write out a 32-bit binary literal, it’d be easy to make mistakes. IDEA: allow a digit-group-separator. (Is underscore a better separator like in other languages? or space?)

Enum  E
    Car      = &B 00 01
 
  Bicycle  = &B 00 10
    Foot     = &B 00 11

    Fastest  = &B 01 00
    Shortest = &B 10 00
    Scenic   = &B 11 00
End  Enum 

 

 

Partial interfaces and modules

Currently in VB you can only write classes that are partial. This is sometimes a problem for people who write automatic code-generators, but is more general than just that. IDEA: allow interfaces and modules to be partial, like they already can in C#.

' a.vb
Partial  Interface  I
     Sub  WrittenByUser()
End  Interface 

  

' a.g.vb
Partial  Interface  I
     Sub  WrittenByCodeGenerator()
End  Interface 

 

 

Params IEnumerable

Currently if you have a ParamArray argument then it must be an array. But people typically like to write methods which take IEnumerable rather than arrays. IDEA: Allow you to declare a method with ParamArray IEnumerable(Of T).

Sub  f( ParamArray  x  As  IEnumerable ( Of  String ))
' If someone invokes f("hello", "world")
' the compiler still translates the callsite into f({"hello", "world"}) 

 

 

TypeOf IsNot

Currently you have to write out negative TypeOf tests in a cumbersome way. IDEA: let you use TypeOf IsNot:

If  Not  TypeOf  sender  Is  Button  Then  ...   '  cumbersome
If  TypeOf  sender  IsNot  Button  Then   ...   '  nicer! 

 

 

Null-propagating operator

This is a highly-voted suggestion on UserVoice, but the comments there are decidedly mixed. IDEA: Not really sure if there are any good clean ideas here.

Dim  y  As  Integer  = x?.y?(3)?.z
' one idea: the ?. and ?() operators are like the normal . and () operators,
' but instead of throwing NullReferenceException, they just return the default
' value of the final part of the expression "z"
 


 Dim  y =  If (x.y(3).z, fallback)
' another idea: re-use the existing binary If operator, but instead of throwing
' NullReferenceException along the way, it jumps straight to using the fallback.

 

  

 

Constructor type inference

Currently it’s a pain to have to supply generic type arguments explicitly when you construct a new object. IDEA: if you attempt to construct a new object of type “List”, say, and there is no non-generic version of List imported, and out of all constructors of all the generic versions of List that are imported there is only one where you can infer the types and it works, then pick that one.

Dim  x =  New  List ({1, 2, 3})   ' should infer New List(Of Integer)({1,2,3}) 

 

Declaration Expressions

Currently there are several places where you declare a variable in one line only to use it in the immediate next line. IDEA: (1) Allow you to declare functions with Out parameters, and allow you to declare variables in-place when you invoke them. (2) Allow you to declare a variable “inline”

' (1) Declaration of an out-parameter function:
Function  TryParse(s  As  String ,  Out  x  As  Integer )  As  Boolean

' (1) Invoking an out-parameter function, and declaring the variable inline:
If  Integer .TryParse(s,  Out  x)  Then  ...             ' this version infers type of x
If  Integer .TryParse(s,  Out  x  As  Integer )  Then  ... ' here explicitly provide type
' Both mean this: Dim x As Integer : If Integer.TryParse(s, x) Then ... 


' (2) Declaring a variable inline:
If  ( Dim  x = GetValue()) > 15  Then  Console .WriteLine(x)
' Means this: Dim x = GetValue() : If x > 15 Then ... 

 

 

Expression-bodied functions

This was one of Mads’ ideas in C#, to allow you to write particularly terse functions and getter-only properties. It’s not clear what would be the VB equivalent syntax for such a feature, or even whether VB would benefit from such terseness.

public  override  int  GetHashCode() => X.GetHashCode() % Y.GetHashCode();
public  double  Dist =>  Math .Sqrt(X * X + Y * Y); 

  

 

Primary constructors

This was one of Mads’ ideas in C#, to allow you to write constructors more easily whose parameters can be used in field/property initializers. It’s not clear what would be the VB equivalent for such a feature, because VB is case insensitive, so this example would be impossible.

class  Point ( int  x,  int  y)
{
   
public  double  X {  get ; } = x;
   
public  double  Y {  get ; } = y;
   
public  double  Z {  get ; } =  Math .Sqrt(X * X + Y * Y);
}