Figure 2 System.Array Methods
Member | Member Type | Description | Rank | Readonly instance property | Returns the number of dimensions in the array. | GetLength | Instance method | Returns the number of elements in the specified dimension of the array. | Length | Readonly instance property | Returns the total number of elements in the array. | GetLowerBound | Instance method | Returns the lower bound of the specified dimension. This is almost always 0. | GetUpperBound | Instance method | Returns the upper bound of the specified dimension. This is almost always the number of elements in the dimension minus 1. | IsReadOnly | Readonly instance property | Indicates if the array is read-only. For arrays, this is always False. | IsSynchronized | Readonly instance property | Indicates if the array access is thread-safe. For arrays this is always False. | SyncRoot | Readonly instance property | Retrieves an object that can be used to synchronize access to the array. For arrays, this is always a reference to the array itself. | IsFixedSize | Readonly instance property | Indicates if the array is a fixed size. For arrays, this is always True. | GetValue | Instance method | Returns a reference to the element located at the specified position in the array. If the array contains value types, then the return value refers to a boxed copy of the element. This rarely used method is required only when you don't know at design time the number of dimensions in an array. | SetValue | Instance method | Sets the element located at the specified position in the array. This rarely used method is required only when you don't know at design time the number of dimensions in an array. | GetEnumerator | Instance method | Return an IEnumerator for the array. This allows use of the C# foreach statement (or equivalent in another language). For multidimensional arrays the enumerator iterates through all the elements with the right-most dimension changing the fastest. | Sort | Static method | Sorts the elements in one array, in two arrays, or in a section of an array. The array element type must implement the IComparer interface or must pass an object whose type implements the IComparer interface. | BinarySearch | Static method | Searches the specified array for the specified element using a binary search algorithm. This method assumes that the array's elements are sorted. The array element type must implement the IComparer interface. You usually use the Sort method before calling BinarySearch. | IndexOf | Static method | Returns the index of the first occurrence of a value in a one-dimensional array, or in a portion of it. | LastIndexOf | Static method | Returns the index of the last occurrence of a value in a one-dimensional array, or in a portion of it. | Reverse | Static method | Reverses the order of the elements in the specified one-dimensional array, or in a portion of it. | Clone | Instance method | Creates a new array that is a shallow copy of the source array. | CopyTo | Instance method | Copies elements from one array to another. | Copy | Static method | Copies a section of one array to another, performing any required casting. | Clear | Static method | Sets a range of elements in the array to 0 or a null object reference. | CreateInstance | Static method | Creates an instance of an array. This rarely used method allows you to dynamically (at runtime) define arrays of any type, rank, and bounds. | Initialize | Instance method | Calls the default constructor for each element in an array of value types. This method does nothing if the elements in the array are reference types. C# doesn't allow you to define default constructors for value types, so this method has no use for arrays of C# types. This method is primarily for compiler vendors. | Figure 3 Using Array.Copy // Create a 2-dim FileStream array
FileStream[,] fs2dim = new FileStream[5, 10];
// Implicit cast to a 2-dim Object array
Object[,] o2dim = fs2dim;
// Can't cast from 2-dim array to 1-dim array
// Compiler error CS0030: Cannot convert type 'object[*,*]' to
// 'System.IO.Stream[]'
Stream[] s1dim = (Stream[]) o2dim;
// Explicit cast to 2-dim Stream array
Stream[,] s2dim = (Stream[,]) o2dim;
// Explicit cast to 2-dim Type array
// Compiles but throws InvalidCastException at runtime
Type[,] t2dim = (Type[,]) o2dim;
// Create a 1-dim Int32 array (value types)
Int32[] i1dim = new Int32[5];
// Can't cast from array of value types to anything else
// Compiler error CS0030: Cannot convert type 'int[]' to 'object[]'
Object[] o1dim = (Object[]) i1dim;
// Array.Copy creates a new array coercing each element in the source
// array to the desired type in the destination array
// The code below creates an array of references to boxed Int32s
Object[] o1dim = new Object[i1dim.Length];
Array.Copy(i1dim, o1dim, i1dim.Length);
Figure 4 More Uses for Copy // Define a value type that implements an interface
struct MyValueType : ICloneable {
•••
}
class App {
static void Main() {
// Create an array of 100 value types
MyValueType[] src = new MyValueType[100];
// Create an array of ICloneable references
ICloneable[] dest = new ICloneable[src.Length];
// Initialize an array of ICloneable elements to refer to boxed
// versions of elements in the source array
Array.Copy(src, dest, src.Length);
}
}
Figure 5 Iterating through an Array Int32 firstYear = quarterlyRevenue.GetLowerBound(0);
Int32 lastYear = quarterlyRevenue.GetUpperBound(0);
Console.WriteLine("{0,4} {1,9} {2,9} {3,9} {4,9}",
"Year", "Q1", "Q2", "Q3", "Q4");
for (Int32 year = firstYear; year <= lastYear; year++) {
Console.Write(year +" ");
for (Int32 quarter = quarterlyRevenue.GetLowerBound(1);
quarter <= quarterlyRevenue.GetUpperBound(1); quarter++) {
Console.Write("{0,9:C} ", quarterlyRevenue[year, quarter]);
}
Console.WriteLine();
}
Figure 6 Access without Index Checking using System;
class App {
unsafe static void Main() {
// Construct an array consisting of 5 Int32 elements
Int32[] arr = new Int32[] { 1, 2, 3, 4, 5 };
// Obtain a pointer to the array's 0th element
fixed (Int32* element = &arr[0]) {
// Iterate through each element in the array
// NOTE: The code below has a bug!
for (Int32 x = 0, l = arr.Length; x <= l; x++) {
Console.WriteLine(element[x]);
}
}
}
}
Figure 7 Safe Code .method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 58 (0x3a)
.maxstack 3
.locals ([0] int32[] arr,
[1] int32& pinned element,
[2] int32 x,
[3] int32 l)
// Construct an array of 5 Int32 elements
IL_0000: ldc.i4.5
IL_0001: newarr [mscorlib]System.Int32
// Initialize the array's elements with values stored in metadata
IL_0006: dup
IL_0007: ldtoken field valuetype '<PrivateImplementationDetails>'/
'$$struct0x6000001-1'
'<PrivateImplementationDetails>'::'$$method0x6000001-1'
IL_000c: call void
[mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class
[mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
// Save the reference to the array in the arr variable
IL_0011: stloc.0
// Get the address of arr's 0th element and save it in element
IL_0012: ldloc.0
IL_0013: ldc.i4.0
IL_0014: ldelema [mscorlib]System.Int32
IL_0019: stloc.1
// Initialize x to 0
IL_001a: ldc.i4.0
IL_001b: stloc.2
// Initialize l to the length of arr
IL_001c: ldloc.0
IL_001d: ldlen
IL_001e: conv.i4
IL_001f: stloc.3
// Branch to the for loop's test
IL_0020: br.s IL_0032
// Calculate element + (4 * x) 4 is the # of bytes in an Int32
IL_0022: ldloc.1
IL_0023: conv.i
IL_0024: ldc.i4.4
IL_0025: ldloc.2
IL_0026: mul
IL_0027: add
// Pass the value at this address to Console.WriteLine
IL_0028: ldind.i4
IL_0029: call void [mscorlib]System.Console::WriteLine(int32)
// Add 1 to x
IL_002e: ldloc.2
IL_002f: ldc.i4.1
IL_0030: add
IL_0031: stloc.2
// for loop test: loop again if x <= l
IL_0032: ldloc.2
IL_0033: ldloc.3
IL_0034: ble.s IL_0022
// End of loop: Put null in element (for safety)
IL_0036: ldc.i4.0
IL_0037: conv.u
IL_0038: stloc.1
// Return from Main
IL_0039: ret
} // end of method App::Main
Figure 8 Disassembled Code .method private hidebysig static void Main() cil managed
{
.entrypoint
// Code size 43 (0x2b)
.maxstack 3
.locals init ([0] int32[] arr,
[1] int32 x,
[2] int32 l)
// Construct an array of 5 Int32 elements
IL_0000: ldc.i4.5
IL_0001: newarr [mscorlib]System.Int32
// Initialize the array's elements with values stored in metadata
IL_0006: dup
IL_0007: ldtoken field valuetype '<PrivateImplementationDetails>'/
'$$struct0x6000001-1'
'<PrivateImplementationDetails>'::'$$method0x6000001-1'
IL_000c: call void
[mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(class
[mscorlib]System.Array,
valuetype [mscorlib]System.RuntimeFieldHandle)
// Save the reference to the array in the arr variable
IL_0011: stloc.0
// Initialize x to 0
IL_0012: ldc.i4.0
IL_0013: stloc.1
// Initialize l to the length of arr
IL_0014: ldloc.0
IL_0015: ldlen
IL_0016: conv.i4
IL_0017: stloc.2
// Branch to the for loop's test
IL_0018: br.s IL_0026
// Pass the element in arr[x] to Console.WriteLine
IL_001a: ldloc.0
IL_001b: ldloc.1
IL_001c: ldelem.i4
IL_001d: call void [mscorlib]System.Console::WriteLine(int32)
// Add 1 to x
IL_0022: ldloc.1
IL_0023: ldc.i4.1
IL_0024: add
IL_0025: stloc.1
// for loop test: loop again if x < l
IL_0026: ldloc.1
IL_0027: ldloc.2
IL_0028: ble.s IL_001a
// Return from Main
IL_002a: ret
} // end of method App::Main
Figure 9 Redimensioning an Array using System;
class App {
static void Main() {
// Construct an array of 3 elements
Int32[] arr = new Int32[] { 1 , 2, 3 };
// Display all the elements in the array
foreach (Int32 x in arr)
Console.Write(x + " ");
Console.WriteLine();
// Redimension the array so that it now contains 5 elements
arr = (Int32[]) Redim(arr, 5);
// Display all the elements in the array
foreach (Int32 x in arr)
Console.Write(x + " ");
Console.WriteLine();
// Redimension the array so that it now contains 2 elements
arr = (Int32[]) Redim(arr, 2);
// Display all the elements in the array
foreach (Int32 x in arr)
Console.Write(x + " ");
}
public static Array Redim(Array origArray, Int32 desiredSize) {
// Determine the types of each element
Type t = origArray.GetType().GetElementType();
// Construct a new array with the desired number of elements
// Each element is the same type as was in the original array
Array newArray = Array.CreateInstance(t, desiredSize);
// Copy the element from the original array in to the new array
Array.Copy(origArray, 0,
newArray, 0, Math.Min(origArray.Length, desiredSize));
// Return the new array
return newArray;
}
}
|