Array Usage Guidelines
For a general description of arrays and array usage see Arrays, and System.Array Class.
Arrays vs. Collections
Class library designers might need to make difficult decisions about when to use an array and when to return a collection. Although these types have similar usage models, they have different performance characteristics. In general, you should use a collection when Add, Remove, or other methods for manipulating the collection are supported.
For more information on using collections, see Grouping Data in Collections.
Array Usage
Do not return an internal instance of an array. This allows calling code to change the array. The following example demonstrates how the array badChars
can be changed by any code that accesses the Path
property even though the property does not implement the set accessor.
Imports System
Imports System.Collections
Imports Microsoft.VisualBasic
Public Class ExampleClass
NotInheritable Public Class Path
Private Sub New()
End Sub
Private Property Path
Get
End Get
Set
End Set
End Property
Private Shared badChars() As Char = {Chr(34),"<"c,">"c}
Public Shared Function GetInvalidPathChars() As Char()
Return badChars
End Function
End Class
Public Shared Sub Main()
' The following code displays the elements of the
' array as expected.
Dim c As Char
For Each c In Path.GetInvalidPathChars()
Console.Write(c)
Next c
Console.WriteLine()
' The following code sets all the values to A.
Path.GetInvalidPathChars()(0) = "A"c
Path.GetInvalidPathChars()(1) = "A"c
Path.GetInvalidPathChars()(2) = "A"c
' The following code displays the elements of the array to the
' console. Note that the values have changed.
For Each c In Path.GetInvalidPathChars()
Console.Write(c)
Next c
End Sub
End Class
[C#]
using System;
using System.Collections;
public class ExampleClass
{
public sealed class Path
{
private Path(){}
private static char[] badChars = {'\"', '<', '>'};
public static char[] GetInvalidPathChars()
{
return badChars;
}
}
public static void Main()
{
// The following code displays the elements of the
// array as expected.
foreach(char c in Path.GetInvalidPathChars())
{
Console.Write(c);
}
Console.WriteLine();
// The following code sets all the values to A.
Path.GetInvalidPathChars()[0] = 'A';
Path.GetInvalidPathChars()[1] = 'A';
Path.GetInvalidPathChars()[2] = 'A';
// The following code displays the elements of the array to the
// console. Note that the values have changed.
foreach(char c in Path.GetInvalidPathChars())
{
Console.Write(c);
}
}
}
You can correct the problem in the preceding example by making the badChars
collection readonly (ReadOnly in Visual Basic). Alternately, you can clone the badChars
collection before returning. The following example demonstrates how to modify the GetInvalidPathChars
method to return a clone of the badChars
collection.
Public Shared Function GetInvalidPathChars() As Char()
Return CType(badChars.Clone(), Char())
End Function
[C#]
public static char[] GetInvalidPathChars()
{
return (char[])badChars.Clone();
}
Do not use readonly (ReadOnly in Visual Basic) fields of arrays. If you do, the array is readonly and cannot be changed, but the elements in the array can be changed. The following example demonstrates how the elements of the readonly array InvalidPathChars
can be changed.
public sealed class Path
{
private Path(){}
public static readonly char[] InvalidPathChars = {'\"', '<', '>','|'}'
}
//The following code can be used to change the values in the array.
Path.InvalidPathChars[0] = 'A';
Using Indexed Properties in Collections
You should use an indexed property only as a default member of a collection class or interface. Do not create families of functions in noncollection types. A pattern of methods, such as Add, Item, and Count, signal that the type should be a collection.
Array Valued Properties
You should use collections to avoid code inefficiencies. In the following code example, each call to the myObj
property creates a copy of the array. As a result, 2n+1 copies of the array will be created in the following loop.
Dim i As Integer
For i = 0 To obj.myObj.Count - 1
DoSomething(obj.myObj(i))
Next i
[C#]
for (int i = 0; i < obj.myObj.Count; i++)
DoSomething(obj.myObj[i]);
For more information, see the Properties vs. Methods topic.
Returning Empty Arrays
String and Array properties should never return a null reference. Null can be difficult to understand in this context. For example, a user might assume that the following code will work.
Public Sub DoSomething()
Dim s As String = SomeOtherFunc()
If s.Length > 0 Then
' Do something else.
End If
End Sub
[C#]
public void DoSomething()
{
string s = SomeOtherFunc();
if (s.Length > 0)
{
// Do something else.
}
}
The general rule is that null, empty string (""), and empty (0 item) arrays should be treated the same way. Return an empty array instead of a null reference.
See Also
Design Guidelines for Class Library Developers | System.Array Class.