I used to work in a VB.Net shop. It wasn't my favorite place, but it gave me an appreciation for modern VisualBasic, instead of old VB6 (which I also had to work on).

Part of what made VB.Net better was that it had more sane defaults. By default it enabled Option Explicit (require variables to be declared before use), and Option Strict (error on any narrowing conversions between data-types). One of its biggest weaknesses, however, was that you could turn those features off, something which was frequently done to make old-style VB6 code more compatible with VB.Net. Arguably, the biggest WTF was that Microsoft promised an "easy" path to upgrade VB6 code to VB.Net, through a mix of compatibility libraries and conversion tools that didn't work.

Which brings us to this VB.Net code that Stephen inherited. It's a small WTF, but so representative of the ways in which things could go very wrong.

Private m_intErrorCode As Integer Public Property ErrorCode() As String Get Return m_intErrorCode End Get Set(ByVal Value As String) m_intErrorCode = Value End Set End Property

The private member is an Integer. The public interface is a String. Every get/set ends up converting between these two data-types. This is the kind of thing that someone has to go out of their way to enable. And yes, if the input value isn't a valid number, this throws an exception.

And this small example hints at a much larger problem: you know this is codebase is a pile of string-ly typed data getting chucked around between modules, stuffed into strongly typed values only at the lowest layers, and is stuffed with unexpected crashes when runtime type checks fail.