Arrays allow processing multiple data items as a set. CLR supports one-dimensional arrays, multi-dimensional arrays, and staggered data (arrays composed of arrays ). All Array types are implicitly derived from the System. Array abstract class, and the latter is derived from System. Object. This means that the array is always a reference type and is allocated on the managed stack. Variables or fields in your application contain references to arrays rather than elements of arrays. The following code makes it clearer:
Int32[] myIntegers; myIntegers = int32[]
C # also supports multi-dimensional arrays. The following example shows several multi-dimensional arrays:
Double[,] myDoubles = Double[,String[,,] myStrings = String[,,];
Point[][] myPolygons = Point[myPolygons[] = Point[myPolygons[] = Point[myPolygons[] = Point[ (Int32 x = ; x < myPolygons[].Length; x++
The previous section shows how to create an array object and how to initialize elements in the array. C # Allow one statement to do two things at the same time. For example:
String[] names = String[] { , };
names = [] { , , };
Group type. In this example, the compiler finds two strings and one null. Since null can be implicitly converted to any reference type (including String), the compiler infer that an array consisting of String references should be created and initialized.
Given the Code:
names = [] { , , };
The compiler reports an error. Although the String and Int32 common base classes are objects, this means that the compiler has to create an Object to reference an array and then pack 123, and let the last array element reference a boxed Int32 with a value of 123. However, the C # team believes that implicit packing of array elements is an expensive operation, so an error is reported when compiling.
In C #, You can initialize the array as follows:
String[] names = { , };
names = { , };
kids = [] { { Name= }, { Name= ( kid
Aidan
Grant
For arrays whose elements are of the reference type, CLR allows implicit conversion of array elements from one type to another. For successful transformation, the two array types must have the same dimension, and there must be an implicit or display conversion from the source type to the target type. CLR cannot convert an array of Value Type elements to any other type. (However, to simulate this effect, you can use the Array. Copy method to create a new Array and populate it with data ). The following shows the array transformation process:
FileStream[,] fs2dim = FileStream[, Object[,] o2dim =Stream[,] s2dim =String[,] st2dim =Int32[] i1dim = Int32[Object[] o1dim =
The Copy method can also perform necessary type conversion when copying each array element. The Copy method can perform the following conversions:
1) bind an element of the value type to an element of the reference type. For example, copy an Int32 [] to an Object.
2) Unpack the element of the reference type into a value-type element. For example, copy an Object [] to Int32.
3) Extend the CLR primitive value type. For example, copy an Int32 [] element to a Double.
4) When copying between two arrays, the compatibility between them cannot be proved only from the array type.
In some cases, it is useful to convert an array from one type to another. This type of feature is called data covariance. When using array covariance, we should be clear about the resulting performance loss.
Note: If you only need to Copy some elements in the Array to another Array, you can select the BlockCopy method of System. Buffer, which is faster than the Array. Copy method. However, the BlockCopy method of Buffer only supports primitive types and does not provide transformation capabilities like the Array Copy method. The Int32 parameter of the method represents the byte offset in the array, rather than the element index. To reliably copy elements from one array to another, use System. array ConstrainedCopy method. This method ensures that the replication is completed without damaging the Array in the target Array, or an exception is thrown. In addition, it does not perform any packing, unpacking, or downward type conversion.
If an array variable is declared as follows:
FileStream[] fsArray;
Many methods can operate on various collection objects, because IEnumerable, ICollection, and IList parameters are used when declaring them. You can pass the Array to these methods, because System. Array also implements these three interfaces. System. Array implements these non-generic interfaces because these interfaces treat all elements as Writable M. Object. However, it is best to enable System. Array to implement the generic form of this interface to provide better type security and performance during compilation.
When an array is passed as a real parameter to a method, a reference to the array is actually passed. Therefore, the called method can modify the elements in the array. If you do not want to modify it, you must generate a copy of the array and pass the copy to the method. Note that the Array. Copy method executes the shortest Copy.
Some methods return a reference to the array. If the method constructs and initializes the array, it is no problem to return the array reference. However, if the method returns a reference to an internal array maintained by a field, you must decide whether to directly access the array and its elements to the caller of the method. If yes, array reference can be returned. But in general, you do not want to obtain this access permission for method calls. Therefore, the method should construct a new Array and call Array. Copy to return a reference to the new Array.
If you define a method to return an array reference, and the array does not contain elements, the method can return null, and can return a reference to an array containing another element. When implementing this method, Microsoft strongly recommends that it return the latter, because this can simplify the Code required to call this method.
Appointment[] app = (Int32 a =; a< app.Length; a++}
Appointment[] app =( app != (Int32 a =; a< app.Length; a++
You can call the static CreateInstance method of the array to dynamically create your own array. This method has several overloaded versions, allowing you to specify the array element type, array dimension, the lower limit of each dimension, and the number of elements in each dimension. CreateInstance allocates memory for the array and saves the parameter information to the overhead part of the memory block of the array. Returns a reference to the array.
The CLR actually supports two different arrays.
1) indicates an array whose minimum value is 0. These arrays are sometimes called SZ arrays or vectors.
2) The lower limit of an unknown one-dimensional or multi-dimensional array.
You can execute the code to actually view the output of different types.
Array a;a = String[a = Array.CreateInstance((String), Int32[] { }, Int32[] { a = Array.CreateInstance((String), Int32[] { }, Int32[] { a = String[, a = Array.CreateInstance((String), Int32[] { , }, Int32[] { , a = Array.CreateInstance((String), Int32[] { , }, Int32[] { ,
For multi-dimensional arrays, The 0th and 1st arrays display the same type name: System. String [,]. At runtime, CLR regards all multi-dimensional arrays as non-zero-base arrays. This will naturally be displayed as System. String [*, *]. However, for multi-dimensional arrays, CLR decides not to use the * symbol to avoid confusion.
Accessing a one-dimensional 0-base array is a little faster than accessing a non-0-base array or multi-dimensional array. First, some special IL commands, such as newarr, ldelem, and ldelema, are used to process one-dimensional 0-base arrays. These special IL commands will cause the JIT compiler to generate optimization code. Secondly, the JIT compiler knows that the for Loop will ask the array elements between 0 and Length-1. Therefore, the code generated by the JIT compiler will test that access to all array elements is within the effective access to the array at runtime.
If the relationship is good, consider the Array (that is, the staggered array) to replace the rectangular array.
The following C # Code demonstrates three methods to access a two-dimensional array:
Int32 c_numElements = Int32 testCount = Int32[,] a2Dim = Int32[][] aJagged = (Int32 x = ; x < c_numElements; x++= sw = (Int32 test = ; test < testCount; test++sw = (Int32 test = ; test < testCount; test++sw = (Int32 test = ; test < testCount; test++ = (Int32 x = ; x < c_numElements; x++ (Int32 y = ; y < c_numElements; y+++= = (Int32 x = ; x < c_numElements; x++ (Int32 y = ; y < c_numElements; y+++= = (Int32* pi = (Int32 x = ; x < c_numElements; x++= x * (Int32 y = ; y < c_numElements; y+++= pi[baseOfDim +
At last, please note that the speed of Security and two-dimensional array access technology is roughly the same. However, considering that its access is a single two-dimensional array (generating a memory allocation), the second does not require many memory allocations as the staggered array does. So its speed is the fastest among all technologies.
If performance is the primary goal, avoid allocating hosted array objects on the stack. Instead, an array should be allocated on the thread stack, which is completed through the stackalloc Statement of C. The stackalloc statement can only create an array consisting of one-dimensional 0-base elements and value-type elements, and the value type cannot include any fields of the reference type. Of course, the memory (array) allocated on the stack will be automatically released when the method returns.
The following code shows how to use C # stackalloc statements:
Int32 width = * pc = Char[width]; = ; (Int32 index = ; index < width; index++- index - ] =< s.Length) ? s[index] : Console.WriteLine( String(pc, Int32 widthInBytes = = widthInBytes / = ; (Int32 index = ; index < width; index++- index - ] =< s.Length) ? s[index] : Console.WriteLine( String(ca.Characters, Char Characters[
1) The type must be a structure (value type); arrays cannot be embedded in the class (reference type.
2) the field or its definition structure must be marked with the unsafe keyword
3) The fixed keyword must be used to mark the array fields.
4) The array must be a one-dimensional 0-base array.
5) The element type of the array must be Boolean, Char, SByte, Byte, Int16, Int32, UInt16, UInt32, Int64, UInt64, Single or Double.
Inline (embedded) arrays are often used for interoperation with unmanaged code, and the unmanaged data structure also has an inline array. However, it can also be used in other cases.