Implicit Typing in C# and VB.NET

Intertech Tutorials

C# and Implicit Typing

In C#, implicit typing can only be used for local variables. You cannot implicitly type member variables, method return values, or method parameters:


// C#
class ThisWillNeverCompile
{
// Error! var cannot be used on field data!
private var myInt = 10;

// Error! var cannot be used as return values
// or parameter types!
public var MyMethod(var x, var y){}
}

In C# 3.0, you are also able to type local arrays implicitly. However, like any array, you cannot mix values when initializing the array. You can, however, have an array with values and default values for a given data type. The current release of VB does not support this syntax.


// C#
static void ImplicitArrays()
{
// a is really int[].
var a = new[] { 1, 2, 3, 4000 };

// b is really double[].
var b = new[] { 1, 1.5, 2, 2.5 };

// c is really string[].
var c = new[] { "we", null, "are", null, "family" };

// myCars is really SportsCar[].
var myCars = new[] { new SportsCar(), new SportsCar()};

// Error! Mixed types!
var d = new[] { 1, "one", 2, "two" };
}

Visual Basic and Implicit Typing

Strictly speaking, like C#, VB does not allow implicit typing of anything other than a local variable. However, it can seem otherwise. Consider the following VB code, which seems to suggest that implicit typing is used to declare a field, parameter, and return value. In reality, this is not the case.


' Is this implicit typing?
Public Class SomeClass
Private myData = 10 ' No specified variable data type!

' No specified return value!
Public Function MyFunction(ByVal myArg)
Return 0
End Function

End Class

In VB, it is legal to omit an As clause for non-local data points but only when Option Strict is Off (the default behavior). When Option Strict is Off, any variable defined without an As clause will default to System. Object. Therefore, you are making use of late binding, which can hurt performance. Notice the following IntelliSense screen capture for the myData field:

linq2-463x173

Like the preceding C# code example, the following VB code will not compile, as Option Strict as been enabled for this code file. Recall that Options can be enabled on a file-by-file basis or via a project-wide setting.


' VB
Option Strict On

' These errors will not be found if Option Strict is Off.
'

Class ThisWillNeverCompile
' Error! Implicit typing cannot be used on field data!
Private myInt = 10

' Error! Implicit typing cannot be used as return values
' or parameter types!

Public Sub MyMethod(ByVal x, ByVal y)
End Sub
End Class

Most VB projects should always enable Option Strict as a project-wide setting. Not only does this prevent ‘lazy’ late binding, but you gain a higher level of type safety when performing widening and narrowing data conversions. The assumption in this class is that VB programmers will always enable Option Strict as a project-wide setting.

Be aware that VB 9.0 now supports Option Infer (On or Off). Option Infer is the setting that enables implicit typing of local variables. By default, every Visual Studio project will have Option Infer enabled. You can change this on a project-wide level using the Compile tab of the My Project property editor.

linq3-480x197

Like other options, Option Infer can be set on a file-by-file basis. Consider the interplay of Option Strict and Option Infer for this single *.vb file.


' VB
Option Infer Off
Option Strict On

Module Program
' These are all errors with the current options!
Sub ImplicitLocalVars()
Dim myInt = 0
Dim myBool = True
Dim myString = "Time, marches on..."
End Sub
End Module

The following table illustrates the end result of combining Option Strict and Option Infer. Recall that Option Strict = Off is the default for new VB projects. Remember Option Infer = On is the default for new VB project.

Option Strict Setting Option Infer Setting Combination Results in Strongly Typed Data? Combination Results in Coding Error?
On On Yes No
On Off Yes, with an As clause. Yes, if your data is declared using without an As clause.
Off Off No No
Off On Yes No

Final Details of Implicit Typing

Implicit typing can also be used within a for each construct. The compiler will ensure that the container is compatible with the iteration variable.


// C#
static void ImplicitVarInForEach()
{
// Array of System.Int32 types.
var evenNumbers = new int[] { 2, 4, 6, 8 };

// Here, item is a System.Int32.
foreach (var item in evenNumbers)
{
Console.WriteLine("Item value: {0}", item);
}
}



' VB
Sub ImplicitVarInForEach()
' Array of System.Int32 types.
Dim myIntArray = New Integer() { 2, 4, 6, 8 }

' Here, item is a System.Int32.
For Each item In myIntArray
Console.WriteLine("Item value: {0}", item)
Next
End Sub

Like a constant variable, the value of an implicitly typed local variable must be assigned at the point of declaration. In C#, implicitly typed local variables cannot be assigned the value of null at the time of declaration but can be assigned to null after the fact. VB does allow the initial assignment of Nothing to implicitly typed local variables. It is permissible for the assigned value to be a literal value or the value of another variable.


// C#
static void ImplicitDataTests()
{
// Error! Must assign a value!
var myData;

// Error! Must assign a value at the time of declaration!
var myInt;
myInt = 0;

// Error! Can’t assign null at declaration!
var myObj = null;

// OK!
var myCar = new SportsCar();
myCar = null;

// Also OK!
var myInt2 = 0;
var anotherInt = myInt2;

// Also OK!
string myString = "Wake up!";
var myData2 = myString;
}




' VB
Option Strict On
Option Infer On

Module MyModule
Sub ImplicitDataTests()

' Error! Must assign a value!
Dim myData

' Error! Must assign a value at the time of declaration!
Dim myInt
myInt = 0

' OK!
Dim myObj = Nothing

' OK!
Dim myCar = New SportsCar()
myCar = Nothing

' Also OK!
Dim myInt2 = 0
Dim anotherInt = myInt2

' Also OK!
Dim myString = "Wake up!"
Dim myData2 = myString
End Sub
End Module

Unlike a COM VARIANT or loosely typed scripting languages, implicitly typed data is indeed strongly typed. The C# compiler will not allow you to assign incompatible values after the initial assignment. The same holds true in VB if Option Strict is enabled.


// C#
// The following code is fine as the compiler knows 's' is a string.
var s = "This variable can only hold string data!";
s = "This is fine.";

// Error! 's' is a string, not an integer!
s = 44;

DO NOT use implicitly typed local variables as a simple time saver. When you know you need an integer, declare an integer. Overuse of implicit typing can make your code confusing to others.

When you are working with LINQ query expressions, you will find implicit typing to be extremely helpful, if not mandatory in some cases. The underlying data type returned from a LINQ query expression is seldom obvious and sometimes impossible to determine. In these cases, implicit typing can be used to hold the result of a LINQ query expression in a strongly typed, simplified manner. As a solid rule of thumb, only make use of implicit typing when working with LINQ queries.


Copyright (c) 2008-2013. Intertech, Inc. All Rights Reserved. This information is to be used exclusively as an online learning aid. Any attempts to copy, reproduce, or use for training is strictly prohibited.