BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 3.0+

C# Implicitly Typed Arrays

With C# 3.0, Microsoft introduced the concept of implicitly typed arrays to the language. With such an array, the type is not specified explicitly in the code. Instead, the compiler decides upon the type to use based upon the array's initial values.

Explicitly Typed Arrays

When using the .NET framework version 2.0, or older versions, you can declare arrays containing a number of items, with each element in the array being either a value type or a reference type. Such arrays can be defined and left unpopulated as in the following example:

int[] nullArray;

Such a declaration leaves the nullArray variable containing null and awaiting later population. You can also declare an array and populate it with a number of default or null values. For example, to create a set of ten integers, all with a default value of zero, you can use the following statement:

int[] intArray = new int[10];

Finally, you can declare and fully populate an array in a single statement using an array initializer, as in the next command. This code creates an array of five strings.

string[] names = new string[] {"Bob", "Sam", "Jim", "Dan", "Mel"};

Each of the three code samples above shows an explicitly typed array. In each case, the type of the array is the first item in the declaration. When using the .NET framework 3.0 or later, you can omit this data type and create implicitly typed arrays.

Implicitly Typed Arrays

Implicitly typed arrays are similar to implicitly typed variables. Rather than explicitly defining the data type of the variable, you specify that the compiler should examine the elements of the array to determine the type that should be applied. This means that type inference may only be applied to arrays that are declared with an array initializer.

To indicate that the type of an array is to be inferred, the initial declaration of a data type is replaced by the "var" keyword. The second reference to the data type, which appears before the two square brackets, is simply omitted altogether. If we take the previous code example and convert it to use implicit typing, we can write the code as follows:

var names = new [] { "Bob", "Sam", "Jim", "Dan", "Mel" };

During a build, the compiler scans the contents of the array initializer and determines that every item is a string. It therefore creates a string array. If you are using Visual Studio, you will notice the Intellisense system also identifies each item in the array as a string. It is important to note that the compiled code is the same as if you had explicitly declared the type; in this context the var keyword and simpler syntax is simply syntactic sugar.

Arrays of Anonymous Types

Implicitly typed arrays become more useful when working with anonymous types. As with previous examples, every element of the array specified in the initializer must be of the same type. The following example creates an array of five objects, each with a Name property, which is a string, and an Age property, which is an integer.

var myArray = new[]
{
    new {Name="Bob", Age=40},
    new {Name="Sam", Age=35},
    new {Name="Jim", Age=24},
    new {Name="Dan", Age=18},
    new {Name="Mel", Age=57}
};

Limitations

The main limitation of implicitly type arrays is that every item in the array must be of a compatible type and that at least one element of that type must appear within the initializer. This leads to workarounds being required in some situations. In the following example, the developer wishes to create an array of nullable integers. However, as the initializer does not contain a nullable integer, the code fails to compile.

var nullables = new [] { 1, 2, 3, null };

To enable the creation of this array, you can either declare its type explicitly or cast one of the elements as a nullable integer, as follows:

var nullables = new [] { (int?)1, 2, 3, null };

The same limitation applies when using inheritance hierarchies or objects of different classes that each implement a shared interface. For example, if we have an IPerson interface that is implemented by both the Employee and Contractor classes, the following array declaration is invalid:

var people = new []
{
    new Employee("Bob"),
    new Employee("Sam"),
    new Contractor("Mel")
};

Again, you can either declare the array with an explicit type to remove this problem or cast one of the elements to the superclass or shared interface.

var people = new []
{
    (IPerson)new Employee("Bob"),
    new Employee("Sam"),
    new Contractor("Mel")
};
25 October 2008