Narrowing & Widening Conversion Gotcha

What is Narrowing & Widening Conversion
Basically there are two type of conversions, Narrowing conversion and Widening conversion. Both these conversions comes into picture whenever type conversion occurs. An important consideration with a type conversion is whether the result of the conversion is within the range of the destination data type. A widening conversion changes a value to a data type that can accommodate any possible value of the original data. Converting from an Integer to a Long is a widening conversion. A narrowing conversion changes a value to a data type that might not be able to hold some of the possible values. Converting from a Long to a Integer is a narrowing conversion.

When does it occurs
Narrowing conversions are done by default i.e. implicitly by the .NET compiler. The compiler doesn't do widening conversions implicitly for you. When you assign a Long variable's value to a Integer variable narrowing conversion is done by default. The compiler automatically treats the number as Integer. But when assign a Integer value to a Long variable, compiler doesn't treat it as a long data type value. Having said that, you need to explicitly tell the compiler that your number is a Long.

Sometimes things can go wrong without your knowledge while these conversions are involved. Lets have a look at following code segment:

Lets consider that you have a form with a ComboBox control dropped on it.

Public Class Form1

Public Class cListItem
Private m_id As Integer
Private m_text As String

Public Sub New( _
ByVal id As Integer, _
ByVal text As String _
Me.m_id = id
Me.m_text = text
End Sub

Public Property ID() As Long
Return m_id
End Get
Set(ByVal value As Long)
m_id = value
End Set
End Property

Public Property Text() As String
Return m_text
End Get
Set(ByVal value As String)
m_text = value
End Set
End Property
End Class

Private Sub Form1_Load( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles MyBase.Load

Dim items As cListItem() = New cListItem(3) {}

items(0) = New cListItem(1, "Test 1")
items(1) = New cListItem(2, "Test 2")
items(2) = New cListItem(3, "Test 3")
items(3) = New cListItem(4, "Test 4")

ComboBox1.DataSource = items
ComboBox1.ValueMember = "ID"
ComboBox1.DisplayMember = "Text"
End Sub

Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles Button1.Click

ComboBox1.SelectedValue = 2
End Sub

End Class
Above code populates the ComboBox with some values. If you click the button it should select the second item in the ComBox, but it doesn't. Why?

When you assign a numeric value '2' to the 'SelectedValue' property of the ComboBox at line "ComboBox1.SelectedValue = 2", the compiler automatically treats the number 2 as an Integer. Since all the combo box items are Long objects, it doesn't find a match. So nothing is selected and you end up with a blank combo box.

The compiler doesn't do widening conversions implicitly for you, so you have to do the conversion explicitly.
' Explicitly convert the Integer to Long
ComboBox1.SelectedValue = 2L
So the moral of the story is to make a practice of converting values to proper types while doing type conversions.

Load form from its String name

In some situations we need to load form from its string name. Lets consider for example, you have stored the list of forms in your application in a database and now you want to load those forms at run-time. The simplest solution for this is that you will write if conditions like this:

' Dummy code
Dim formName As String

formName = "form1" ' Get the form name from database.

If formName = "form1" Then
Dim frm1 As New Form1
ElseIf formName = "form2" Then
Dim frm2 As New Form2
ElseIf formName = "form3" Then
Dim frm3 As New Form3
ElseIf formName = "form4" Then
Dim frm4 As New Form4
End If
But what if you have 40 more forms in your application. So basically writing that much if conditions is not a good solution. To accomplish the goal we need to use Reflection. Here is the code:

Imports System.Reflection

Public Class Form2

Private Sub Button1_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs _
) Handles Button1.Click

Dim frm As New Form
Dim formName As String = "Form1"

formName = Me.GetType.Assembly.GetName.Name & "." & formName
frm = DirectCast(Me.GetType.Assembly.CreateInstance(formName), Form)
End Sub

End Class

.NET Tips and Tricks

Vertical Block Selection:

Let’s assume a situation where we have 20 lines of code and now we need to delete first 10 characters of every line. What we do normally do here is go to first line and select the first 10 characters and delete it. Again go to second line, select the first 10 characters and delete it. We follow these steps for all remaining lines. Quite a boring work, isn’t it? There is a nice feature in Visual Studio .NET IDE called ‘Vertical Block Selection’ present since from .NET 2005 edition. To delete 10 characters of every line, press and hold the ALT key and then select the text of every line in vertical direction with mouse. That’s it. It’s simple but very handy.

Convert a piece of VB6 code to VB.NET:

If we want to convert VB6 project to VB.NET the easiest solution for this is we open the VB6 project straight forward in .NET IDE. This starts the ‘Visual Basic Upgrade Wizard’ and converts the entire project. Now what if want to convert a small piece of VB6 code to VB.NET. There is no provision for this in Visual Basic Upgrade Wizard. The solution is, create a sample VB.NET Windows application and go to Tools menu and select ‘Upgrade Visual Basic 6 code’. Paste the VB6 code here and click the Upgrade button. The upgraded code will inserted in currently open document at the current cursor position. If the VB6 code is referring to any COM component then you can add reference to it from the Reference tab of Upgrade Visual Basic 6 code window.

Writing Comments in a better way:

You can add better procedure level comments by typing three single quotes, just type ‘’’ just above procedure name, function name, property name, etc. Visual Studio will automatically insert a documentation template whenever the three single quotes are typed within a VB.NET source code file. Inserting comments this way basically enhance the information presented about a class, constructor or other member. Although these comments can be added to the source code at any point, it is usual to ensure that documentation is inserted immediately before the definition of classes, functions, subroutines and properties, thereby allowing these members to be documented.

Setting Tab Order easily:

How do you set the tab order of controls in your application? Setting tab order for controls in a bit boring task for me since from VB6 days, but now in .NET things are changed. To set the tab order, you simply select all controls, and then select Tab Order from the View menu. Then just click the controls in the order you want the tabs to sit. As you click each control, the tab order will be displayed on the control to keep you up to date. Press ESC when you have finished.

Code Snippets:

Code snippets are one of the best productivity features introduced in Visual Studio 2005. It allows you to quickly insert fragments of code to avoid tedious typing (such as typing a for loop) or to give you a template of how to accomplish a certain task (such as sending data over the network).

There are two ways to insert a snippet. You can type the snippet's alias in the code editor and press TAB twice to insert the snippet immediately. After the code snippet has been inserted, you can press TAB and SHIFT+TAB to jump to different fields within the snippet. This allows you to quickly change the parts of code that need to be modified.

If you don't remember your code snippet's alias, you can also insert it by pressing "Ctrl+K, Ctrl+X" within the code editor or do a mouse right-click with the mouse and select Insert Snippet.... This shows the code snippet picker, which enables you to browse all the snippets that are applicable to your current programming language and to choose the one you want to insert.

The most exciting part of the code snippet feature is that you can create your own snippets. You can do it from ‘Code Snippets Manager’ window found in Tools menu.

Use Regions:

A very nice feature of the Visual Studio .NET code editor is the concept of Regions. Regions are great way to organize your code. You can create named regions directly in our source code. We can then expand and collapse regions in the editor to hide or show code based. For example, you could create a region called “Public Properties” and put all your property code there like I have done below:

There are five basic regions into which we can group our code: Private Fields, Constructors, Public Methods, Public Properties, and Private Methods. Off course other region can be created as per demand. This is up to us how we organise the code.

Line Numbering:

Did you know that you can add line numbers to your code files in VS.NET? Line numbers are especially helpful if discussing a block of code with someone else, as you can refer to a specific line numbers. It is configured through the Options dialog of Tools menu.

Tools|Options|Text Editor|All Languages|General|Line numbers.

If you want to set this option only for any specific language, then choose the appropriate language instead of ‘All Languages’.

Store Commonly Used Text/Code in Toolbox:

One of the nice VS.NET productivity tricks is to store text/code/re-usable things as toolbox items. To add text to the Toolbox, highlight it in the code editor, drag it over to your toolbox, and drop it when the mouse pointer changes to a rectangle. Thereafter, you can simply drag and drop the toolbox items to your code editor for reuse.

Don't Cut and Paste controls:

Don't cut and paste controls that have event code in them. It removes their handlers which can cause massive headaches.

For example, If you add a button to a form, put some code in its click event, then cut and paste it back to the form, the code in the click event will no longer work.

What happens is the code is still there, but it removes the "Handles button1.Click" from the end of the sub since the IDE is using the background compiler.

You can only imagine what would happen if you had 100 controls on your form and you cut and paste them for some reason (like putting them in a frame or panel)

Drag the controls instead, they will retain the links to the handlers.

Advanced Members:

Some members of classes in the framework are invisible to VB.NET by default. While many may truly be advanced members that you will not likely use, but some are common ones . You can turn on these advanced members from:

Tools|Options|Text Editor|Basic

Keyboard IDE Launch:

I like this one a lot because I do it myself for many programs that don't need fully qualified paths to run.

If you want to open the VS.NET IDE you can simply hit Start|Run and type devenv and hit ENTER key.

Some parts of this article taken from vbforums.