Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 158 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 20:

Консольные приложения в С#

< Лекция 19 || Лекция 20: 1234567891011

Модификаторы для параметров методов

Программист может поручить компилятору контроль за параметрами методов, обозначив одни как входные, другие - как выходные. Для таких целей в C# предусмотрен ряд модификаторов, перечисленных в таблице

Таблица 20.8 . Модификаторы для параметров методов C#
Модификатор Назначение
(нет) - по умолчанию in ) Если модификатор никак не помечен, то по умолчанию считается, что это входящий параметр in для передачи переменной как значения. Вместо пропуска можно поставить in - результат будет таким же.
out Маркирует возвращаемый методом параметр.
ref Маркирует входной параметр, передаваемый по ссылке. Изменение параметра внутри метода означает изменение самих данных, хранящихся вне метода и адресуемых ссылкой.
params Этот модификатор позволяет передавать целый набор параметров как единое целое. В любом методе может быть только один модификатор params и параметр с этим модификатором должен стоять последним в списке параметров метода.

Проиллюстрируем прменение модификаторов на примере

using System;
  
namespace Test
{
class Test
{
//***************************************
public int Add(int x, int y)
{
  return x + y;
}
//***************************************
public void Add(int x, int y, out int sum)
{
  sum = x + y;
}
//***************************************
public void UpperCaseThisString(ref string str)
{
  // Возвращает символьную строку с верхнем регистре
  str = str.ToUpper();
}
//***************************************
public void DisplayArrayOfInt(string msg, params int[] list)
{
  Console.Write(msg);
  for(int i = 0; i < list.Length; i++)
    Console.Write(" {0}", list[i]);// Вывод в строку
}
  
//***************************************
//***************************************
static void Main()
{
  Test test = new Test();
  Console.WriteLine("5 + 10 = {0}", test.Add(5, 10));

  int sum; // Инициализировать необязательно - выходной 
  test.Add(50, 100, out sum);
  Console.WriteLine("50 + 100 = {0}", sum);
  
  string message = "\nПривет студентам от Снеткова!";
  Console.WriteLine("Перед обработкой:{0}", message);
  test.UpperCaseThisString(ref message);
  Console.WriteLine("После обработки:{0}", message);
  
  int[] arrayInt = new int[3]{1, 2, 3};
  test.DisplayArrayOfInt("Вывод из массива целых:", 
    arrayInt);
  test.DisplayArrayOfInt("\nВывод списка из трех целых:",
     11, 22, 33);
  test.DisplayArrayOfInt("\nВывод списка из пяти целых:", 
      55, 66, 77, 88, 99);
        
  while(true);
}
}
}
Листинг 20.38 . Применение модификаторов параметров методов

Результат примера

5 + 10 = 15
50 + 100 = 150
Перед обработкой:
Привет студентам от Снеткова!
После обработки:
ПРИВЕТ СТУДЕНТАМ ОТ СНЕТКОВА!
Вывод из массива целых: 1 2 3
Вывод списка из трех целых: 11 22 33
Вывод списка из пяти целых: 55 66 77 88 99

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

Можно передавать в качестве множественных параметров любые типы данных, если определить в списке формальных аргументах массив элементов базового типа. В этом случае механизм передачи будет подстраиваться под тип фактических аргументов, передаваемых функции. Приведем пример, где метод будет принимать массив объектов и в зависимости от их типа принимать решение по обработке.

using System;
  
namespace Test
{
class Person
  {
  private string Name;
  private int Age;
  
  //***************************************
  // Конструктор
  public Person(string name, int age)
  {
  Name = name;
  Age = age;
  }
  //***************************************
  // Конструктор по умолчанию
  public Person(){}
  //***************************************
  public void PrintInfo()
  {
  Console.WriteLine("Имя={0}; Возраст={1}", Name, Age);
  }
  }
//****************************************************************
class Test
  {
  //***************************************
  // Что же мне пришлют на этот раз?
  public void DisplayArrayOfObject(params object[] list)
  {
  for(int i = 0; i < list.Length; i++)
  {
  // Относится ли текущий объект из переданного
  // массива объектов к классу Person?
  if(list[i] is Person)
    ((Person)list[i]).PrintInfo();
  else
    Console.WriteLine(list[i]);
  }
  }
//***************************************
static void Main()
  {
  // Создали объект только
  // для того, чтобы вызвать его метод
  Test test = new Test();
  
  // Создаем сотрудника
  Person person = new Person("Студент 
    Вильгельм И.А.", 21);
  // Передаем сотрудника и другие разнотипные объекты в нужном 
  // количестве методу, объявленному с модификатором params
  test.DisplayArrayOfObject(
    "Переменное число параметров любого типа",
    "T 001 TT",
    12345,
    person,
    Math.PI,
    true,
    "Привет студентам от Снеткова",
    "..................... и т.д.");
  
  while(true);
  }
}
}
Листинг 20.39 . Передача методу произвольных параметров

Результат примера

Переменное число параметров любого типа 
T 001 TT
12345
Имя=Студент Вильгельм И.А.; Возраст=21 
3,14159265358979
True
Привет студентам от Снеткова 
..................... и т.д.

В языке C# нет операций адресации и разадресации & и *, как это имеет место быть в C и C++. Вся передача обеспечивается использованием ссылок с явным или неявным использованием модификатора ref.

Массивы в C#

Массивы в C# - это набор однотипных элементов, доступ к которым производится по их числовому индексу. Наряду с массивами элементов простого встроенного типа (имеющим псевдонимы системных типов) существуют массивы объектов, структур, интерфейсов. Массивы могут быть одномерными (простыми) и многомерными. Массивы объявляются путем помещения квадратных скобок ( операторов индекса ) между типом массива и его именем. После объявления переменной массива при запросе под него памяти указывается количество элементов для хранения.

Следует помнить, что размер массива задается при его создании, но не при объявлении. Если мы создаем массив фиксированного размера, то использование ключевого слова new обязательно. Если при объявлении мы массив сразу инициализируем, то new необязательно - размерность массива определит компилятор. Индексация элементов массива начинается с нуля.

В C++ список инициализации может по количеству элементов не соответствовать заказанной размерности массива. В этом случае компилятор игнорирует лишние элемемнты списка или часть элементов оставляет неинициализированными. В C# заказанная размерность массива должна строго соответствовать количеству элементов в списке инициализации, иначе компилятор выдаст ошибку.

Одномерные массивы

using System;
  
namespace Test
{
class Test
{
  //***************************************
  private void DisplayString(string subTitle, string[] list)
  {
  Console.WriteLine(subTitle);
  for(int i = 0; i < list.Length; i++)
    {
    Console.WriteLine("{0}) {1}", i, list[i]);
    }
  }
  //***************************************
  private void DisplayInt(string subTitle, int[] list)
  {
  Console.WriteLine(subTitle);
  for(int i = 0; i < list.Length; i++)
  {
  Console.WriteLine("{0}) {1}", i, list[i]);
  }
  }
  //***************************************
static void Main()
{
  string title =  "************************
    ********************\n"
    + "\tОдномерные массивы:\n"
    + "*****************************
    ***************\n";
  Console.WriteLine(title);
  
  // Создадим объект для применения методов
  // DisplayString() и DisplayInt()
  Test test = new Test();
  
  // Создадим ссылочную переменную типа массива с адресом null
  string[] str1; 
  // Запросим память у системы для 10 элементов и запомним адрес.
  str1 = new string[10]; 
  test.DisplayString( "Строковый массив без 
    инициализации элементов.\n"
    + "Строковые элементы по умолчанию\n"
    + "инициализируются пустыми строками."
    , str1);
  
  // Поэлементная инициализация с использованием индексов
  // и той же ссылки с новым адресом.
  // Адрес старого массива потерян в куче. Утерянную 
  // память системе вернет сборщик мусора Garbare Collector
  str1 = new string[7];
  str1[0] = "Колян";
  str1[1] = "Вован";
  str1[2] = "Иван";
  str1[3] = "Болван";
  str1[4] = "Чурбан";
  test.DisplayString("\nПоэлементная 
    инициализация с использованием индекса.\n"
    + "Старая адресуемая память утеряна 
    безвозвратно:", str1);
  
  // Создадим ссылочную переменную и сразу инциализируем ее адресом.
  int[] int1 = new int[5]; 
  test.DisplayInt("\n" 
    + "Числовой массив фиксированного размера.\n"
    + "Элементы по умолчанию инициализируются нулями."
    , int1);
  
  // Создаем ссылку на массив. Инициализируем ее адресом, запросив
  // память с фиксированным количеством элементов,
  // и сразу инициализируем элементы массива.
  // Размер списка инициализации должен строго соответствовать
  // запрошенной размерности массива.
  int[] int2 = new int[5] {11, 22, 33, 44, 55};
  test.DisplayInt(
    "\n" 
    + "Запрошенный размер массива должен\n"
    + "строго соответствовать списку инициализации."
    , int2);
  
  // Создаем ссылку на массив. Инициализируем ее адресом, запросив
  // память без указания количества элементов. Количество элементов
  // определит компилятор при инициализации списком.
  // Используем оператор new.
  int[] int3 = new int[] {11, 22, 33, 44, 55, 66, 77};
  test.DisplayInt(
    "\n" 
    + "Размер по списку инициализации, \nпамять 
    запрашивается по new"
    + ":"
    , int3);
  
  // Создаем ссылку на массив. Инициализируем ее адресом, запросив
  // память без указания количества элементов. Количество элементов
  // определит компилятор при инициализации списком.
  // Оператор new не используем.
  int[] int4 = {11, 22, 33, 44, 55, 66, 77, 88, 99};
  test.DisplayInt(
    "\n" 
    + "Размер по списку инициализации, \nпамять 
    запрашивается без new"
    + ":"
    , int4);
      
  while(true);
  }
  }
}
Листинг 20.40 . Одномерные массивы

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

********************************************
  Одномерные массивы:
******************************************** 
  
Строковый массив без инициализации элементов.
Строковые элементы по умолчанию
инициализируются пустыми строками.
0)
1)
2)
3)
4)
5)
6)
7)
8)
9)
  
Поэлементная инициализация с использованием индекса.
Старая адресуемая память утеряна безвозвратно:
0) Колян
1) Вован
2) Иван
3) Болван
4) Чурбан
5)
6)
  
Числовой массив фиксированного размера.
Элементы по умолчанию инициализируются нулями.
0) 0
1) 0
2) 0
3) 0
4) 0
  
Запрошенный размер массива должен
строго соответствовать списку инициализации.
0) 11
1) 22
2) 33
3) 44
4) 55
  
Размер по списку инициализации, 
память запрашивается по new:
0) 11
1) 22
2) 33
3) 44
4) 55
5) 66
6) 77
  
Размер по списку инициализации, 
память запрашивается без new:
0) 11
1) 22
2) 33
3) 44
4) 55
5) 66
6) 77
7) 88
8) 99
< Лекция 19 || Лекция 20: 1234567891011
Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?