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 about using collections, see Collections and Data Structures.
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 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
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 cannot correct the problem in the preceding example by making the badChars
array readonly (ReadOnly in Visual Basic). You can clone the badChars
array and return the copy, but this has significant performance implications. See the subsection that follows, Properties that Return Arrays, for details. The following code example demonstrates how to modify the GetInvalidPathChars
method to return a clone of the badChars
array.
Public Shared Function GetInvalidPathChars() As Char()
Return CType(badChars.Clone(), Char())
End Function
public static char[] GetInvalidPathChars()
{
return (char[])badChars.Clone();
}
Properties that Return Arrays
You should use collections to avoid code inefficiencies caused by properties that return arrays. 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
for (int i = 0; i < obj.myObj.Count; i++)
DoSomething(obj.myObj[i]);
For more information, see Choosing Between Properties and Methods.
Fields that Return Arrays
Do not use readonly (ReadOnly in Visual Basic) fields of arrays. If you do, the array is read-only and cannot be changed, but the elements in the array can be changed. The following code example demonstrates how the elements of the read-only 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
Use an indexed property only as a default member of a collection class or interface. Do not create families of functions in non-collection types. A pattern of methods, such as Add, Item, and Count, signals that the type should be a collection.
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
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.
Portions Copyright 2005 Microsoft Corporation. All rights reserved.
Portions Copyright Addison-Wesley Corporation. All rights reserved.
For more information on design guidelines, see the "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" book by Krzysztof Cwalina and Brad Abrams, published by Addison-Wesley, 2005.