Учебное пособие (1077022), страница 4
Текст из файла (страница 4)
Значение переменной: " + RefTest);ParamByRef(ref RefTest);Console.WriteLine("Вызов функции ParamByRef. Значение переменной: " + RefTest);int x = 2, x2 = 0, x3 = 0;ParamOut(x, out x2, out x3);Console.WriteLine("Вызов функции ParamOut. x={0}, x^2={1}, x^3={2}", x, x2, x3);26ParamArray("Вывод параметров: ", 1, 2, 333);//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// Использование yield//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Console.Write("\nИспользование yield: ");foreach (string st in YieldExample())Console.Write(st);Console.ReadLine();}/// <summary>/// Передача параметра по значению/// </summary>static void ParamByVal(string param){param = "Это значение НЕ будет передано в вызывающую функцию";}/// <summary>/// Передача параметра по ссылке/// </summary>static void ParamByRef(ref string param){param = "Это значение будет передано в вызывающую функцию";}/// <summary>/// Выходные параметры объявляются с помощью out/// </summary>static void ParamOut(int x, out int x2, out int x3){x2 = x * x;x3 = x * x * x;}/// <summary>/// Переменное количество параметров задается с помощью params/// </summary>static void ParamArray(string str, params int[] ArrayParams){Console.Write(str);foreach (int i in ArrayParams)Console.Write(" {0} ", i);}/// <summary>/// Значения, возвращаемые с помощью yield воспринимаются как значения массива/// их можно перебирать с помощью foreach/// </summary>static IEnumerable YieldExample(){yield return "1 ";yield return "2 ";yield return "333";}}}На основе данного примера рассмотрим основные конструкции языкаC#.273.6.1 Пространства имен и сборкиПрограмма начинается с операторов using, каждый из которыхуказывает пространство имен для библиотечных классов.
Любой класс вязыке C# должен быть объявлен в каком-либо пространстве имен сиспользование оператора namespace.Пространства имен представляют собой древовидную структуру. Вкаждой ее ветви содержатся вложенные классы и вложенные пространстваимен. Если с помощью оператора using подключаются классы какого-либопространства имен, напримерusing System;то классы вложенных пространств имен при этом автоматически неподключаются.Поэтомуихнеобходимоподключатьотдельнымидирективами:usingusingusingusingSystem;System.Collections;System.Linq;System.Text;Пространства имен представляют собой логическую структуру длясистематизации классов. Выясним, как эта структура соотносится соткомпилированными классами.Откомпилированный бинарный код для платформы .NET хранится вфайлах сборок (assembly). Файл может иметь расширение .dll или .exe поаналогии с библиотеками и исполняемыми файлами ОС Windows.
Ноданные файлы содержат бинарный код, выполняющийся только наплатформе .NET. Если же она не установлена, то ОС Windows не запуститтакой исполняемый файл.Файлы сборок следует подключать в разделе References проекта (рис.3). В русской версии Visual Studio раздел References называется Ссылки.При нажатии правой кнопкой мыши на пункт References открываетсядиалог по добавлению новых сборок.28Рис. 3. Файлы сборок.Рис. 4. Указание пространства имен и сборки в справочной системе.Из рисунка 3 видно, что раздел References содержит те же значениячто и операторы using. Однако это принципиально разная информация.
Вразделе References находятся имена физических файлов сборок – файлов,29которые содержат бинарный код, присоединяемый к проекту. Секция usingссылается на логическое название в дереве пространства имен.При этом возможна ситуация, когда классы из одного и того жепространства имен находятся в разных сборках, и наоборот, одна сборкасодержит классы из разных пространств имен. Поэтому в справочнойсистеме Microsoft для каждого класса указано как имя сборки, так ипространство имен (рис 4).Стоит отметить, что концепция пространства имен – спецификаMicrosoft.В классическом языке С++ пространства имен отсутствуют, вместоних применяется подключение заголовочных файлов. Однако в версииязыка С++, предлагаемой Microsoft, используется такой же механизмпространств имен как и в C#.В Java существует концепция похожая на пространства имен – пакеты(package).
По аналогии с пространством имен каждый класс может бытьвключен в пакет. Но в данной концепции существуют ограничения – пакетявляется каталогом файловой системы, в который вложены файлы классов.Если имя пакета составное (содержит точку), то это предполагаетвложенность соответствующих каталогов. Один файл в Java не можетсодержать более одного класса, следовательно, файл-класс однозначносоответствует пакету-каталогу. Пространства имен в языке C# – болеегибкий механизм, однако сторонники Java полагают, что подобнаяжесткость позволяет избежать ошибок и несоответствий, встречающихся впространствах имен.Далее в тексте программы приведены конструкции:namespace Structures{class Program{…}}30Команда namespace объявляет пространство имен, а class – класс.Команда namespace может содержать несколько классов.
Чтобы сослатьсяна класс Program следует применить директиву:using Structures;Основной исполняемый метод консольного приложения – метод Main:static void Main(string[] args){…}Строковыймассивпараметровметодаargsсодержитпараметры(аргументы) командной строки, которые могут быть заданы при вызовеконсольного приложения.Рис. 5. Задание аргументов командной строки при отладке.В Visual Studio в целях отладки данные параметры можно указать всвойствах проекта. Для этого нужно нажать правую кнопку мыши наназвании проекта Structures, выбрать в контекстном меню пункт Свойстваи установить параметры командной строки, что показано на рис.
5.31Далее в методе Main рассматриваются основные виды конструкцийязыка C#, которые очень похожи на соответствующие конструкции языковC++ и Java.3.6.2 Условные операторыПример условного оператора if:if (str == "строка1"){Console.WriteLine("if: str == \"строка1\"");}else{Console.WriteLine("if: str != \"строка1\"");}В качестве условия проверяется значение логического типа, которыйотсутствует в стандартном С++, но есть в Паскале, Java, C#.Условный оператор вопрос-двоеточие выполняется аналогично тому,что в С++ и Java.
До знака вопроса указывается логическое выражение.Если оно истинно, то выполняется код от вопроса до двоеточия, еслиложно – код после двоеточия.Пример оператора вопрос-двоеточие:string Result = (str == "строка1" ? "Да" : "Нет");Оператор switch выполняется аналогично тем, что в С++ и Java.Пример оператора switch:switch (str){case "строка1":Result2 = "строка1";break;case "строка2":case "строка3":Result2 = "строка2 или строка3";break;default:Result2 = "другая строка";break;32}В круглых скобках после switch указывается проверяемое выражение,а после case – возможные варианты проверяемых значений.Если значения после switch и case совпадают, то выполняютсяоператоры, указанные в case до первого оператора break.
Если операторbreak не указан, то выполняются операторы следующей по порядку секцииcase, поэтому обычно каждую секцию case завершает оператор break. Еслини один оператор case не удовлетворяет условию, то выполняютсяоператоры секции default.3.6.3 Операторы сопоставления с образцомОператоры сопоставления с образцом (pattern matching) – этоклассическая особенность языков программирования, использующихфункциональный подход, таких как F#, Scala, Erlang, Haskell.В языке C# данная возможность появилась, начиная с версии 7.Сопоставление с образцом похоже на условные операторы и поэтомупостроено на их основе.Пусть дан массив объектов, который содержит строки и целые числа:object[] array1 = { 1, "строка 1", 2, "строка 2", 3 };Для того чтобы расширить условный оператор до операторасопоставления с образцом в язык C# была добавлена конструкция is.Пример сопоставления с образцом на основе условного оператора if:foreach(object obj in array1){if(obj is int i1){Console.WriteLine("Число -> " + i1.ToString());}else if (obj is string s1){Console.WriteLine("Строка -> " + s1);}}33В данном примере в цикле foreach по очереди перебираются элементымассива.Если элемент массива соответствует целому числу «obj is int i1», то онавтоматически приводится к целому типу и помещается в переменную i1.Далее с ним можно выполнять необходимые действия, в примере этовывод в консоль.Если элемент массива соответствует строке «obj is string s1», то онавтоматически приводится к строке и помещается в переменную s1.Результаты вывода в консоль:Число -> 1Строка -> строка 1Число -> 2Строка -> строка 2Число -> 3Вторым вариантом сопоставления с образцом в C# являетсяиспользование оператора switch.Пример сопоставления с образцом на основе оператора switch:foreach (object obj in array1){switch(obj){case string s1:Console.WriteLine("Строка -> " + s1);break;case int i1 when i1 > 2:Console.WriteLine("Число большее 2 -> " +i1.ToString());break;case int i1:Console.WriteLine("Число -> " + i1.ToString());break;}}В этом случае в каждом операторе case указывается проверяемый типи переменная, в которую сохраняется результат приведения типа.С использованием ключевого слова when можно задавать такназываемые «охранные выражения» (guards), которые накладывают34дополнительныеограничениянапроверку.Вданномпримеревозможность приведения к целому типу проверяется дважды, случай i1>2рассматривается отдельно и возникновение такого случая проверяется спомощью охранного выражения.Результаты вывода в консоль:Число -> 1Строка -> строка 1Число -> 2Строка -> строка 2Число большее 2 -> 33.6.4 Операторы циклаСчетный цикл for такой же как в C++ и Java.















