Исследование MS Visual С#, страница 6

              ManSpace.Man.Finalize() Line 79

которая сообщает о том, что деструктор был вызван из функции Finalize, унаследованной нашим классом от класса Object. Эта виртуальная функция вызывается в процессе сборки мусора, но точный момент времени, когда это произойдет предсказать невозможно и не нужно. Это прерогатива CLR. Отметьте, что в C# и в управляемой (managed) версии C++ мы не должны переопределять (override) Finalize в пользовательском классе (например, в классе Man). Если мы хотим произвести какие-то действия, до того как сборщик мусора уничтожит наш объект, то мы должны сделать это в теле деструктора.

Многомерные массивы

Массивы могут иметь более одного измерения. Многомерный массив переменных любого типа можно объявить двумя различными способами. Первый способ несколько непривычен для тех, кто привык работать с конструкциями языка С++. Второй — более понятен, но тоже требует усилий при восприятии и времени на привыкание. Важно отличать многомерные массивы (multidimensional arrays) и массивы массивов (jagged arrays). В следующем фрагменте (создайте новый файл) показано как объявить и пользоваться двухмерным массивом.

static void Main()

{

uint[,] a =    // Объявляем многомерный массив целых

{

  {1,2,3},

  {4,5,6}

};

Console.WriteLine ("2-dimensional array:\n");

for (int i=0; i <= a.GetUpperBound(0); i++)  // Пробег по нулевому измерению

{

  for (int j=0; j < a.GetLength(1); j++)// Пробег по первому измерению

       Console.WriteLine ("a[{0},{1}] = {2}", i, j, a[i,j]);

}

  //==== Хотим увидеть значения фундаментальных свойств

Console.WriteLine("\n\nRank = " + a.Rank);

Console.WriteLine("Rows = " + a.GetLength(0));

Console.WriteLine("Columns = " + a.GetLength(1));

Console.WriteLine("Length = " + a.Length);

}

Значительно меньше усилий требуется для бесформатного вывода массива. Для этого вместо двух вложенных циклов for используйте цикл foreach.

foreach (uint i in a) // Пробег по всем элементам массива

Console.Write (i+", ");

Задание

Предположим, что мы захотели узнать размер памяти, занимаемой нашим массивом. Ответ на этот вопрос вы, конечно, знаете (6 * 4 = 24). Но мы хотим подтвердить эту оценку с помощью свойств или методов класса Array и типа System.UInt32. В программе на языке С++ для этой цели мы применили бы операцию sizeof. Как оказалось, в рамках языка С# ответ получить не так просто, потому, что она не желает привязываться к платформе.

1.  Объявите трехмерный массив строк. Сколько байт памяти он занимает?

2.  Объявите трехмерный массив типа double без начальной инициализации. В следующей за ним строке кода присвойте ему определенные значения.

3.  Переопределите массив, объявленный в предыдущем задании так, чтобы изменились размерности по всем трем его измерениям. При выполнении этого оператора для массива будет выделена новая память, а кто займется старой?

Первая задача легко решается в рамках .NET Framework version 1.1. В этой версии (в пространстве System) появился новый класс Buffer, который позволяет легко манипулировать массивами примитивных типов (primitive types). Следующий фрагмент иллюстрирует некоторые возможности нового класса.

static void Main ()

{

  int[] a = { 1, 2, 3, 4, 5};

  int[] b = { 0, 0, 0, 0, 0, 6, 7, 8, 9, 10};

  int lenA = Buffer.ByteLength (a),     // Длина массива в байтах

     lenB = Buffer.ByteLength (b);

  Console.WriteLine("Array a length: {0} bytes", lenA);

  foreach (int i in a)

     Console.Write("{0},  ",i);

  Console.WriteLine("\n\nArray b length: {0} bytes", lenB);

  foreach (int i in b)

     Console.Write("{0},  ",i);

  Buffer.BlockCopy (a, 0, b, 0, lenA);

  Console.WriteLine("\n\nAfter Block copy operation array a :");

  foreach (int i in a)

     Console.Write("{0},  ",i);

  Console.WriteLine("\n\nArray b: ");

  foreach (int i in b)

     Console.Write("{0},  ",i);

  Console.WriteLine("\n\n");

}

Массивы массивов

Рассмотрим альтернативный способ объявления массивов, который в документации  снабжен эпитетом jagged (разорванный, отрезанный, см. Help4Reference). Такие массивы следует представлять как массивы массивов. Принципиальным отличием их от массивов предыдущего типа является то, что размерности подчиненных массивов могут быть разными. Технология использования таких массивов демонстрируются в следующем примере (лучше создать новый файл).

static void Main()

{

int[][] a =    // Объявляем массив массивов целых

{

  new int[]{1},

  new int[]{2,3,4},

  new int[]{5,6,7,8,9}

};

Console.WriteLine ("Jagged array:\n");

for (int i=0; i <= a.GetUpperBound(0); i++)  // 0-е изм-е работает как и ранее

{

  Console.WriteLine();

      //==== Число столбцов переменно, поэтому первое измерение не работает

  for (int j=0; j < a[i].GetLength(0); j++)

     Console.Write ("a[{0}][{1}] = {2},  ",i,j,a[i][j]);

}

Console.WriteLine("\n\nRank = " + a.Rank);

Console.WriteLine("Length = " + a.Length + '\n');

for (int i=0; i < a.GetLength(0); i++)   // foreach выглядит по-другому

{

  foreach (int j in a[i])

     Console.Write (j+", ");

}

Console.WriteLine ("\n");

}

Другие методы класса Array

Какими методами, унаследованными от класса System.Array мы можем пользоваться при манипулировании объектами из массива men? Оказывается, далеко не всеми, так как наш класс Man еще не достаточно развит. Но некоторые методы мы уже можем применять. При выполнении следующих заданий не выбрасывайте класс Helper, пусть он всегда будет с вами (в пространстве имен).

Задание

Создайте массив ссылок на объекты класса Man и примените к массиву следующие методы: