May 19

Arrays in .NET – part III

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

Now that you know the types of arrays you can create and how to simplify its initialization, it’s time to see what we can do with then. As I’ve said previously, all arrays inherit from the base Array type. In practice, this means that all array instances we create inherit automatically all the properties and methods defined by the base Array class. This is great because it makes working with arrays easy. Here’s an example:

var ints = new []{1, 2};
var numElements = ints.Length;
var shallowCopy = new Int32[2];
ints.CopyTo( shallowCopy, 0 );

As you’ve probably noticed, you can only use Length and CopyTo because they were defined by the Array type (which is automatically used as a base type of our Int32 array). But there’s more: the Array class introduces several utility methods which you can use to find an element or to sort an array. The next snippet illustrates the use of the static IndexOf static method for getting the position of the first element of an array:

var ints = new []{1, 2, 30, 40};
var pos = Array.IndexOf( ints, 2 );//returns 1

The Array type does expose several static methods, so you probably should take a moment or two to look at its docs…But there’s still more! All arrays implicitly implement IEnumerable, ICollection and IList interfaces. Unfortunately, the Array base class doesn’t implement the generic version of these interfaces. However, the CLR does implement these generic interfaces for all the types in the hierarchy of all single-dimension zero-lower bound arrays that hold *reference* types. So, when we have something like this:

var strs = new[] {"hi", "there"};

The CLR will not only implement the IEnumerable<String>, ICollection<String> and IList<String> on the “type String[]”, but it will also implement the generic versions of those interfaces for all String’s base types (in this case, there’s only Object). Notice that this doesn’t happen for value types (in those cases, you’ll get the generic versions of the interfaces, but only for that concrete value type) because reference and value items use different layout memory placements. Notice also that implementing these interfaces is really important for allowing arrays to be used in LINQ expressions…

And that’s it for now. In the next post, I’ll keep my previous promise and we’ll see how to create non-zero-lower bound arrays. Stay tuned!