C#. Передача в функцию одномерных и многомерных массивов экземпляров класса как ref и out параметров




Передача в функцию одномерных и многомерных массивов экземпляров класса как ref и out параметров


Содержание


Поиск на других ресурсах:

1. Особенности передачи ссылок на массивы экземпляров класса с использованием модификаторов ref и out

Существует 2 способа передачи в функцию ссылок на массивы экземпляров класса:

  • передача по значению. В этом случае, массив полностью копируется в функцию. Изменение значений массива внутри функции не изменит эти значения в вызывающем коде;
  • передача по ссылке. В этом случае используются модификаторы ref или out. При такой передаче можно изменить количество элементов в массиве, перераспределить память для каждого элемента, заполнить новыми значениями эти элементы массива.

Итак, при передаче массива с модификаторами ref или out:

  • можно изменять значения самой ссылки. Это значит, что можно перераспределить память для массива и его элементов и заполнить новыми значениями элементы массива;
  • изменение значений элементов массива внутри функции будет отображаться в вызывающем коде.

 

2. Передача одномерного массива типа int как ref-параметра. Пример

В нижеследующем примере разработан класс Integer, содержащий один внутренний параметр value.

В тестируемом классе Program объявляются следующие элементы:

  • статическая функция GetArray(), формирующая массив случайных чисел типа Integer. Функция получает входным параметром массив A типа Integer[] как ref-параметр и перераспределяет память для самой ссылки A. Функция по новому выделяет память для любого экземпляра и заполняет поля экземпляра значениями. Изменение значений фиксируется в вызывающей функции main();
  • статическая функция SumIntegers() – предназначена для вычисления суммы целочисленных значений value массива типа Integer. Функция получает входным параметром массив типа Integer[] как ref-ссылку.

После завершения работы программы не нужно освобождать память (как в C++). Память будет освобождена автоматически при так называемой «сборке мусора».

using System;

namespace ConsoleApp2
{
  // Класс Integer - ссылочный тип
  class Integer
  {
    public int value; // целочисленное значение
  }

  class Program
  {
    // Статическая функция GetArray() генерирует (формирует) массив случайных чисел,
    // масив передается как ref-параметр, можно изменять саму ссылку A
    static void GetArray(ref Integer[] A)
    {
      // 1. Инициализировать генератор случайных чисел
      Random rnd_num = new Random();

      // 2. Изменить количество элементов в массиве A - перераспределить память
      A = new Integer[6]; // изменяется сама ссылка - выделить память для 6 экземпляров

      // 3. Выделить память для каждого экземпляра отдельно
      for (int i = 0; i < A.Length; i++)
      {
        A[i] = new Integer();
      }

      // 4. Заполнить массив случайными целыми числами в пределах [0; 10]
      for (int i = 0; i < A.Length; i++)
      {
        // Все переменные в массиве будут отображаться за пределами данной функции
        A[i].value = rnd_num.Next(0, 10);
      }

      // 5. Возврат из функции
      return;
    }

    // Статическая функция, которая находит сумму элементов массива,
    // массив передается по ссылке (с модификатором ref)
    static int SumIntegers(ref Integer[] A)
    {
      int sum = 0;
      for (int i=0; i<A.Length; i++)
      {
        sum += A[i].value;
      }
      return sum;
    }

    static void Main(string[] args)
    {
      // Передача ref-массива экземпляров класса в метод

      // 1. Объявить массив типа Integer
      const int MAX_ITEMS = 8; // максимально-допустимое количество элементов в массиве
      Integer[] Array;

      // 2. Выделить память для MAX_ITEMS элементов, сформированных случайно
      Array = new Integer[MAX_ITEMS];

      // 3. Выделить память для каждого элемента типа Integer
      for (int i = 0; i < Array.Length; i++)
        Array[i] = new Integer();

      // 4. Заполнить массив Array фиксированными значениями от 1 до Array.Length
      for (int i=0; i<Array.Length; i++)
      {
        Array[i].value = i + 1;
      }

      // 5. Вывести массив на экран в строку
      Console.WriteLine("Items in Array:");
      for (int i=0; i<Array.Length; i++)
      {
        Console.Write($"{Array[i].value}\t");
      }

      // 6. Заполнить массив Array случайными числами
      // с помощью вызова функции GetArray()
      GetArray(ref Array); // функция статическая, изменяет массив изнутри

      // 7. Вывести измененный массив на экран
      Console.WriteLine("\nArray after random forming:");
      for (int i=0; i<Array.Length; i++)
      {
        Console.Write($"{Array[i].value}\t");
      }

      // 8. Вычислить сумму элементов измененного массива и вывести ее на экран
      int summ = Program.SumIntegers(ref Array);
      Console.WriteLine($"\nsumm = {summ}");
    }
  }
}

Результат выполнения программы:

Items in Array:
1 2 3 4 5 6 7 8
Array after random forming:
4 3 8 9 7 7
summ = 38


 

3. Передача одномерного массива экземпляров класса как out-параметра. Пример

Данный пример очень близок к примеру в п. 2 (передача массива как ref-параметра). Отличие только в функции GetArray(), в которой модификатор ref заменен на модификатор out.

using System;

namespace ConsoleApp2
{
  // Клас Integer - ссылочный тип
  class Integer
  {
    public int value;
  }

  class Program
  {
    // Статическая функция GetArray() генерирует (формирует) массив случайных чисел,
    // массив передается как out-параметр, можно изменять саму ссылку A
    static void GetArrayOut(out Integer[] A)
    {
      // 1. Инициализировать генератор случайных чисел
      Random rnd_num = new Random();

      // 2. Изменить количество элементов в массиве A
      A = new Integer[6]; // изменяется сама ссылка - выделить память для 6 экземпляров

      // 3. Выделить память для каждого экземпляра отдельно
      for (int i = 0; i < A.Length; i++)
      {
        A[i] = new Integer();
      }

      // 4. Заполнить массив случайными целыми числами в пределах [0; 10]
      for (int i = 0; i < A.Length; i++)
      {
        // Все изменения в массиве будут отображаться за пределами данной функции
        A[i].value = rnd_num.Next(0, 10);
      }

      // 5. Возврат из функции
      return;
    }

    // Статическая функция, которая находит сумму элементов массива,
    // массив передается по ссылке (с модификатором ref)
    static int SumIntegers(ref Integer[] A)
    {
      int sum = 0;
      for (int i=0; i<A.Length; i++)
      {
        sum += A[i].value;
      }
      return sum;
    }

    static void Main(string[] args)
    {
      // Передача out-массива экземпляров класса в метод

      // 1. Объявить массив типа Integer
      const int MAX_ITEMS = 8; // максимально-допустимое количество элементов в массиве
      Integer[] Array;

      // 2. Выделить память для MAX_ITEMS элементов, сформированных случайно
      Array = new Integer[MAX_ITEMS];

      // 3. Выделить память для каждого элемента типа Integer
      for (int i = 0; i < Array.Length; i++)
        Array[i] = new Integer();

      // 4. Заполнить массив Array фиксированными значениями от 1 до MAX_ITEMS
      for (int i=0; i<Array.Length; i++)
      {
        Array[i].value = i + 1;
      }

      // 5. Вывести массив на экран в строку
      Console.WriteLine("Items in Array:");
      for (int i=0; i<Array.Length; i++)
      {
        Console.Write($"{Array[i].value}\t");
      }

      // 6. Заполнить массив Array случайными числами
      // с помощью вызова функции GetArray()
      GetArrayOut(out Array); // функция статическая, изменяет массив изнутри

      // 7. Вывести измененный массив на экран
      Console.WriteLine("\nArray after random forming:");
      for (int i=0; i<Array.Length; i++)
      {
        Console.Write($"{Array[i].value}\t");
      }

      // 8. Вычислить сумму элементов измененного массива и вывести ее на экран
      int summ = Program.SumIntegers(ref Array);
      Console.WriteLine($"\nsumm = {summ}");
    }
  }
}

Результат выполнения программы:

Items in Array:
1 2 3 4 5 6 7 8
Array after random forming:
1 4 5 9 5 2
summ = 26

 

4. Передача двумерного массива экземпляров класса как ref-параметра. Пример

В примере демонстрируется передача в функцию двумерного массива экземпляров класса как ref-параметра. Если нужно реализовать передачу в функцию двумерного массива как out-параметра, то модификатор ref заменяется на модификатор out.

В программе реализованы следующие классы и методы:

  • класс Integer – реализует целое число;
  • статический метод GetArray2D(), который получает параметрами ссылку на двумерный массив A экземпляров класса Integer и ссылку на переменные Rows, Columns (количество строк и количество столбцов). В этом методе выделяется память для массива, формируются размеры и значение его элементов. Все изменения внутри функции будут отображаться в вызывающем коде (функции main());
  • статический метод SumIntegers2D(), который получает параметрами ref-ссылку на массив и его размерность. Метод вычисляет сумму элементов массива;
  • статический метод PrintArray2D(), который получает массив и его размерность по значению (без модификаторов ref или out). Данный метод выводит массив на экран.

Текст приложения, созданного по шаблону Console Application следующий.

using System;

namespace ConsoleApp2
{
  // Класс Integer - ссылочный тип
  class Integer
  {
    public int value;
  }

  class Program
  {
    // Статическая функция GetArray2D() генерирует (формирует) массив случайных чисел.
    // Массив передается как ref-параметр, можно изменять саму ссылку A.
    // Параметры Rows, Columns возвращают количество столбцов и строк массива.
    static void GetArray2D(ref Integer[,] A, ref int Rows, ref int Columns)
    {
      // 1. Инициализировать генератор случайных чисел
      Random rnd_num = new Random();

      // 2. Сформировать размер массива
      Rows = 3; // количество строк
      Columns = 4; // количество столбцов

      // 3. Выделить память для двумерного массива в целом
      A = new Integer[Rows, Columns];

      // 4. Выделить память для каждого экземпляра отдельно
      for (int i = 0; i < Rows; i++)
        for (int j = 0; j < Columns; j++)
        {
          A[i, j] = new Integer();
        }

      // 5. Заполнить массив случайными целыми числами в пределах [0; 10]
      for (int i = 0; i < Rows; i++)
        for (int j = 0; j < Columns; j++)
        {
          // Все изменения в массиве будут отображаться за пределами данной функции
          A[i, j].value = rnd_num.Next(0, 10);
        }

      // 6. Возврат из функции
      return;
    }

    // Статическая функция, которая вычисляет сумму элементов двумерного массива.
    // Массив передается по ссылке (с модификатором ref).
    // Параметры Rows, Columns передаются по значению.
    static int SumIntegers2D(ref Integer[,] A, int Rows, int Columns)
    {
      int sum = 0;
      for (int i = 0; i < Rows; i++)
        for (int j = 0; j < Columns; j++)
        {
          sum += A[i, j].value;
        }
      return sum;
    }

    // Статическая функция PringArray2D(), которая выводит двумерный массив на экран.
    // Функция получает массив A, размеры массива m, n. Параметры передаются по значению
    static void PrintArray2D(Integer[,] A, int m, int n)
    {
      for (int i = 0; i < m; i++)
      {
        for (int j = 0; j < n; j++)
        {
          Console.Write("{0}\t", A[i, j].value);
        }
        Console.WriteLine();
      }
    }

    static void Main(string[] args)
    {
      // Передача двумерного ref-массива экземпляров класса в метод

      // 1. Объявить ссылку на двумерный массив типа Integer
      Integer[,] Array2D = null;
      // 2. Установить количество строк и стобцов в массиве
      int m, n;
      m = 2;
      n = 3;

      // 3. Сформировать массив с помощью функции GetArray2D()
      GetArray2D(ref Array2D, ref m, ref n);

      // 4. Вывести сформированный массив на экран
      Console.WriteLine("Array2D:");
      PrintArray2D(Array2D, m, n);

      // 5. Вычислить сумму элементов массива и вывести ее на экран
      int summ = SumIntegers2D(ref Array2D, m, n);
      Console.WriteLine($"summ = {summ}");
    }
  }
}

Результат работы программы

Array2D:
5 1 7 6
7 7 8 9
7 2 3 7
summ = 69

 


Связанные темы