Why doesn't concatenation work with non intrinsic types ?

Posted Tue, Apr 25 2006 12:59 by bill
If you used VB.NET, you might have noticed that you can't do concatenation on non intrinsic types. For example, you couldn't have:

Dim myCustomer as New Customer("Barney")
Dim s as String
s = "customer name is " & myCustomer
 
The last line would fail.  But you could write :
 
 s = String.Concat("customer name is " , myCustomer)
 
String.Concat in the above example will call on the ToString method that every .NET object has.
 
So you're probably saying about now, "Well if the & operator is Concatenation, then why doesn’t it behave the same as String.Concat does ?"  Good question !!
 
I think it has a lot to do with the language history.  In previous versions of VB, you use to be able to access non indexed default properties of objects implicitly.  Code such as :
s = Label1 & TextBox1
 
would compile the same as :
 
s = Label1.Text & textBox1.Text
 
Now if VB.NET allowed the implicit conversion to string, the code would compile to:
 
s = Label1.ToString & textBox1.ToString
 
Which is a very different thing indeed.  Instead of text like
   "Name : Barney"
 you'd have something like
 
"System.Windows.Forms.Label, Text: Name : System.Windows.Forms.TextBox, Text: Barney"
 
So by not allowing the implicit concatenation, the VB team helped prevent a lot of obscure little bugs you might not have realized till runtime.  By making these a compile time error you realize as you write the code you need to explicitly state if you want to call the .ToString method or perhaps the .Text property.  Unfortunately this only helps those who have Option Strict On.
 
With Option Strict Off however, if the variables are typed As Object then the code will compile and probably result in a runtime exception being thrown.
 
So although the work around is to explicitly state .ToString (or .Text depending on your need), it might be actually nicer if the default was to call .ToString but make it a configurable warning if you don't explicitly state that.  That way you'd get the same design time feedback, the ability to have greater conformity with the framework,  and any implicit code is not going to throw runtime exceptions on you.
 
The question then would be is the change worth the effort ?  Would it break existing apps, versus does it break code that expects default properties.  Is it better to have a runtime exception than the wrong string ??
 
The more I think about this, especially looking forward, looking at empowering dynamic code, late binding et al, then I really think having it call .ToString is the preferable option.  The chance of it breaking code that is written expecting default properties  (al la Vb6), is incredibly small, and that code as is will be broken anyway at runtime.  IOW: the code that does get broken is already broken, so the issue of which is the better break seems hardly the guiding principles for the language <g>
 
I think a configurable warning that can be applied to either or BOTH strict on and strict off code is actually the best approach.  And allowing ToString to be called on all types will provide for far more robust dynamic code.