May 19

Arrays in .NET – part II

Posted in .NET Basics C#      Comments Off on Arrays in .NET – part II

In the first post of the series, I’ve talked about the several types of arrays you can define on your .NET apps. What I didn’t mention at the time is that C# allows you to create and initialize an array with a single instruction:

var ints = new Int32[] {1, 2, 3};

When the compiler finds code like the one shown in the previous snippet, it will automatically create an array big enough for storing all the items specified in the initialization list (in this case, the array’s size will be 3) and it will automatically store the all the items specified in the initialization list in the corresponding index (ex.: value 1 will be stored at index 0). Notice that ints type isn’t specified and it’s inferred from the right hand expression. In fact, we could even save a few key strokes by omitting the Int32 type from the initialization list:

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

When the compiler analyses the previous code, it will try to find the closest base type from all the expressions defined on the initialization list. In the previous example, we only have Int32 literal values, so the compiler will automatically use the Int32 type. If you don’t explicitly set the type of the elements in the array like we did in the previous snippet, then you have to take some care. For instance, you shouldn’t mix reference and value types:

var ints = new [] {"1", 2, 3};//error CS0826: No best type found for implicitly-typed array

This error might confuse novice users at first because we all know that all types inherit (directly or indirectly) from Object, right? So, why doesn’t the compiler simply infers that we want an array of Object elements? Well, I think it could do that. However, that would result in a boxing operation for storing the integer value. Since boxing is a somewhat “dangerous” operation (it might introduce some subtle bugs), then compiler opted for not doing this type of inferring. So, if you do really want to mix reference and value types, you do need to be specific about the type of each element that is going to be stored in the array:

var ints = new Object[] {"1", 2, 3};

Btw, and since we’re talking about shortcuts for initializing arrays, there’s still one final option for cutting down the number of key strokes used:

Int32[] ints = {1, 2, 3};

Unfortunately, this strategy force us to specify the type of variable on the left (notice the use of Int32[]). Since I’m a “var lover”, I really don’t use this syntax a lot. Btw, I‘m still not convinced that forcing a compiler error on something like this is a good idea:

var ints = {1, 2, 3};//error CS0820: Cannot initialize an implicitly-typed local variable with an array initializer

I can understand the decision made about the boxing issue I’ve mentioned before, but why (oh why???) can’t the compiler infer the type only from expression used on the right side of the assignment?

Before ending, it’s also important to understand that the “shortcuts” associated with the reduced “newing” expressions are really useful when we need to work with anonymous types:

var ints = new[] {
    new {Name = "Luis", Age = 35},
    new {Name = "Jose", Age = 20}

Without being able to infer the type from each of the expressions defined by the elements of the array, there would be no way for us to create a new array (because we don’t really know the name that will be given to the anonymous type created by the compiler).

And I’d say that’s all for now! Stay tuned for more…