NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Managed Arrays

Using Managed Extensions for C++, a managed array can be declared by using the __gc keyword or by containing a managed object type. Because managed arrays are allocated from the managed heap, these arrays have additional criteria and features for declaration and usage when compared to standard (unmanaged) arrays:

The following example declares and instantiates a simple managed array of integers:

void main ()
{
   int MyIntArray __gc[]= new int __gc[100];
}

To construct a managed String object from an array of type wchar_t characters, there is no need to zero-terminate the array if it is managed. However, if the wchar_t array is unmanaged, it must be zero-terminated. The following code example demonstrates this:

void main()
{
   String* s = new String(L"ab");

   wchar_t s1 __gc[] = new wchar_t __gc[2];   // array of two wchar_t's
   s1[0] = L'a';
   s1[1] = L'b';
// no zero-termination

   wchar_t s2[3];
   s2[0] = L'a';
   s2[1] = L'b';
   s2[2] = 0;   //must be zero-terminated

   String* str1 = new String(s1);

   if(s->Equals( str1 ))
      Console::WriteLine(S"managed passed");

   if(s->Equals( s2 ))
      Console::WriteLine(S"unmanaged passed");
}

Automatic Array Initialization

When allocating a managed array, the values of the array are automatically initialized to a standard value. This value is determined by the type of the managed array. The following table lists the possible value types and their respective default initialization values.

Value type of array Default initialization value
C++ primitive data type (int, char, and others) Zero initialized.
Managed class Zero initialized.
Value type V (a value array) The default constructor for the value type is applied to each array element.

Multidimensional Arrays

Managed Extensions also support managed arrays with multiple dimensions. The number of dimensions is equal to the number of commas in the declaration plus one. The following example declares a two-dimensional managed array of type Int32:

Int32 MyArray[,] = new Int32[10,20];   // Two dimensions
for(int row = 0; row < MyArray->GetLength(0); ++row)
{
   for(int col = 0; col < MyArray->GetLength(1); ++col)
      MyArray[row,col] = row+col;
}
Warning   The standard C++ comma operator cannot be used inside managed array indices unless it is nested within parentheses.

Array Covariance

For managed arrays, Managed Extensions support the concept of covariance. Array covariance means that, given two types (A and B), an array value of type A can be treated as a reference to an array value of type B, provided there is an implicit reference conversion from B to A. With Managed Extensions, this implicit conversion is available if one class is a direct or indirect base class of the other.

Note   Array covariance is not supported for arrays of value class types.

For instance, the following code sample demonstrates this relationship by declaring several classes (Base, Derived, Derived2, and Derived3) and then initializing them in various ways:

__gc struct Base { int i; };
struct Derived : Base {};
struct Derived2 : Base {};
struct Derived3 : Derived {};
__gc struct Other { short s; };
void main()
{
   Derived* d[] = new Derived*[100];
   Base* b[] = d;   // OK by array covariance
   b[0] = new Other;   // Error (compile time)
   b[1] = new Derived2;   // Error (run-time exception)
   b[0] = new Base;   // Error (run-time exception), must be "at least" a Derived.
   b[1] = new Derived;   // ok
   b[0] = new Derived3;   // ok
}

As part of the support for array covariance, assignments to elements of reference type arrays include a run-time check that ensures that the value being assigned to the array element is actually of a permitted type. If the type is not permitted, an exception System::ArrayTypeMismatchException is thrown.

See Also

Introduction to Managed Extensions for C++