GOTCHA 34 Defining an array isn t consistent


GOTCHA #34 Defining an array isn't consistent

Most of the application code I write is in C#. However, I have been involved in a few projects where I had to mix languages and write some VB.NET code. The fact that the .NET Framework class library (FCL) is the same for C# and VB.NET gives me the confidence that I can switch between the languages with maximum ease. But my confidence has been shaken when I have come across code that looks correct but doesn't work the way I expect it to.

When dealing with arrays, quite a bit of confusion is inherited from the earlier languages. While C-derived languages have zero-based indexes, VB6 used one-based indexes. However, in VB.NET, the index is zero-based. Well, can you say that all .NET languages are consistent now?

Suppose you are a C# developer and you write the code in Example 4-9.

Example 4-9. Array allocation

C# and VB.NET (Array)

   //Test.cs part of C# project Iterateover.exe using System;   namespace IterateOver {     class Test     {         [STAThread]         static void Main(string[] args)         {             object[] objects = new object[3];               for(int i = 0; i < 3; i++)             {                 objects[i] = new object();             }               foreach(Object anObj in objects)             {                 Console.WriteLine(anObj.GetHashCode());             }         }     } } 

You create an array of objects and set each element to an object instance. Then you use foreach to traverse the array and print the hash code of each object. The output is shown in Figure 4-8.

Figure 4-8. Output from Example 4-9


Now suppose you are asked to convert this code to VB.NET. That shouldn't be too difficult, right? So, here you go, your VB.NET version of the above code is shown in Example 4-10.

Example 4-10. VB.NET version of Example 4-9

C# and VB.NET (Array)

   'Test.vb - VB.NET Port of Test.cs   Module Test       Sub Main()         Dim objects() As Object = New Object(3) {}           For i As Integer = 0 To 2             objects(i) = New Object         Next           For Each anObj As Object In objects             Console.WriteLine(anObj.GetHashCode())         Next     End Sub   End Module 

That's a straightforward port. You changed the syntax from C# to the appropriate syntax in VB.NET. But when you execute the VB.NET code, you get the output shown in Figure 4-9.

Figure 4-9. Output from Example 4-10


What went wrong? It first printed the hash code for the three objects as you would expect, and then it threw a NullReferenceException. The reason for this problem is that, in VB.NET, when you declared new Object(3) {}, you actually created an array of size 4 instead of size 3. Consider the code in Example 4-11.

Example 4-11. Array size differences

C# and VB.NET (Array)

   //MyCollection.cs part of CSLib.dll using System;   namespace CSLib {     public class MyCollection     {         public int[] Values         {             get { return new int[10]; }         }     } }   'MyCollection.vb part of VBLib.dll Public Class MyCollection       Public ReadOnly Property Values()         Get             Return New Integer(10) {}         End Get     End Property   End Class   'TestModule.vb in VBUser.exe Module TestModule       Sub Main()         Dim obj1 As New CSLib.MyCollection         Dim obj2 As New VBLib.MyCollection           Console.WriteLine("Size of arrays")         Console.WriteLine("C# created: {0}", obj1.Values.Length)         Console.WriteLine("VB.NET created: {0}", obj2.Values.Length)       End Sub   End Module 

In C# you create an array using the syntax new int[10], while in VB.NET you use new int(10) {}. It looks like you're doing the same thing in both, but when you run the program you get the output shown in Figure 4-10.

Figure 4-10. Output from Example 4-11


Here's the crux of the problem: when you create an array in VB.NET, you specify the maximum index value. In C#, you specify the maximum size (one more than the maximum index value).

IN A NUTSHELL

Use caution creating arrays, and know the difference in how C# and VB.NET declare them. In C#, you specify the maximum size of the array. In VB.NET, you specify the maximum allowed index value.

SEE ALSO

Gotcha #31, "Optional parameters break interoperability" and Gotcha #33, "Name collision with keywords breaks interoperability."



    .NET Gotachas
    .NET Gotachas
    ISBN: N/A
    EAN: N/A
    Year: 2005
    Pages: 126

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net