1. Общие сведения о программирова нии. Этапы решения задач. Язы́к программи́ров ания — формальная знаковая система, предназначенна я для записи компьютерных программ. {Язык программирова ния определяет набор лексических, синтаксических и семантических правил, задающих внешний вид программы и действия, которые выполнит исполнитель (компьютер) под ее управлением.}. Постановка задачи; Анализ и исследование задачи, модели; Разработка Алгоритма; Программирова ние( пр: выбор ЯП) 2. Жизненный цикл программы Возникновение и исследование идеи, управление, анализ требований, проектирование , программирова ние, тестирование и отладка, ввод в действие, эксплуатация и сопровождение, завершение эксплуатации. 3. Критерии качества проги Правильность программы, надёжность, эффективность, модифицируем ость, возможность многократного использования, стиль программирова ния 4. Понятие алгоритма и его свойства Алгоритм – всякая система вычислений, выполняемых по строго определённым правилам, которая какоголибо числа шагов заведомо приводит к решению задачи. Конечность, Понятность, Дискретность, Определенност ь, Результативнос ть, Массовость, Эффективность задачи представляется последовательность ю отдельных шагов, и каждый шаг алгоритма выполняется за конечное время О-Каждый шаг алгоритма должен быть однозначно определён и не должен допускать произвольной трактовки. К-должен закачнчиваться за опр-ое колв-во шагов. Р-Алгоритм имеет некоторое число входных величинаргументов. П-Каждый шаг алгоритма должен быть простым, чтобы устройство, могло выполнить его 1 действием. М-Должен быть применён для некоторого класса задач Д-процесс решения Э-Приводить алгоритм к минимальному числу шагов не изменяя решения 5. Способы записи алгоритма. Вербальный, когда алгоритм описывается на человеческом языке Символьный, опис. с помощью набора символов Графический, опис. с помощью графических изображений 6. Классификация языков программирова ния. Языки программирова ния высокого уровня. Процедурное( это структурное (Паскаль) и Операционное (ассемблер, фортран) Непроцедурное ( Обратное (С++) и Декларативное (Логическое и Функциональное)) ЯП выс ур – ЯП с сильной абстракцией от деталей компьютера. ( С++, Питон, ДжаваСкрипт) Лексические основы языка С#. Общая структура программы. Состоит из using System; class Example { //Любая программа начинается с вызова метода 7. Main() public static void Main() { Console.Write(“ Hello”); } } Стандартные типы данных языка C#. C# – строго типизированны й язык. Это означает, что компилятор не позволит работать с переменной до тех пор, пока не задан ее тип (т.е. переменная не описана). 8. 9. Лексические основы языка С#. Знаки операций. Знак операции – это один или более символов, определяющих действие над операндами. Знаки операций обеспечивают формирование и последующее вычисление выражений. Один и тот же знак операции может употребляться в различных выражениях и поразному интерпретироваться в зависимости от контекста. При вычислении значений выражений учитывается приоритет операций. Менять его можно с помощью скобок. Арифметические: унарные + и –, бинарные +, -, *, /, %, унарные ++ и – –. Операции отношения: <, >, <=, >=, == (равно), != (не равно) 10. Лексические основы языка С#. Идентификато ры, константы и переменные. Идентификаторы В C# идентифи катор представ ляет собой имя, присваиваемое методу, переменной или любому другому определяемому пользователем элементу программы. Идентификатор ы могут состоять из одного или нескольких символов. Имена переменных могут начинаться с любой буквы алфавита или знака подчеркивания. Константы — это постоянные значения, которые известны во время компиляции и не изменяются во время выполнения программы. Константы должны объявляться с модификатором const. Только встроенные типы C# (за исключением System.Object) могут быть объявлены как const. Пользовательск ие типы, включая классы, структуры и массивы, не могут объявляться как const. Прежде чем использовать переменную, ее нужно объявить. Присвоить – значит установить текущее значение переменной. Например, int n; // целочисленная переменная n типа int sbyte tiny; // целочисленная переменная tiny типа sbyte 11. Консольный ввод-вывод в языке С#. Console.Write(S) ; Console.Read(); Есть разный форматный вывод, но он бесполезен. Когда выводим, можно ставить «{0бесконечно}, массив из того, что надо поставить на места» Console.WriteLine( “В феврале {0,3} или {1,5} дней.“, 28,29); Результат: В феврале 28 или 29 дней. 12. Разветвляющи еся алгоритмы. Условный оператор в языке С#. Оператор if обеспечивает передачу управления на одну из двух ветвей вычислений. Оператор if в зависимости от истинности условия выполняет соответствующ ий блок кода: If (условие) { // делаем, когда истина } Else { // делаем, когда ложь } Если в блоке только одна команда, то скобки { } можно опустить. Условие в операторе является выражением логического типа (bool), т.е. оно может быть либо истинным, либо ложным. 13. Разветвляющи еся алгоритмы. Операторпереключател ь. Оператор switch – на одну из произвольного числа ветвей По сути, он вместо бесконечного else if, switch(выражение) { case значение_1: // блок операторов 1 break; case значение_2: // блок операторов 2 break; ... default: // блок операторов N break; Циклы со счетчиком. постусловием. } 14. Алгоритмы и программы циклических структур. Общая схема цикла. 18. Алгоритмы и программы циклических структур. Вложенные циклы. 16. Алгоритмы и программы циклических структур. Циклы с предусловием. 17. Алгоритмы и 15. Алгоритмы и программы циклических структур. программы циклических структур. Циклы c 19. Алгоритмы и программы циклических структур. Итерационные циклы. Итерация – это единичное выполнение тела цикла. Т.е любой цикл, где условие – кол-во выполнений является итерационным. Самый популярный – for-loop 20. Операторы передачи управления. Инструкция break Оператор break завершает выполнение ближайшего внешнего оператора итерации (то есть цикла for, foreach, while или do) или оператора switch. Оператор break передает управление оператору, который расположен после завершенного оператора (если таковой есть). Инструкция continue Оператор continue начинает новую итерацию ближайшего внешнего оператора итерации (то есть цикла for, foreach, while или do), как показано в следующем примере: for (int i = 0; i < 5; i++) { Console.Write($"Itera tion {i}: "); if (i < 3) { Console.WriteLine("s kip"); continue; } Console.WriteLine("d one"); } // Output: // Iteration 0: skip // Iteration 1: skip // Iteration 2: skip // Iteration 3: done // Iteration 4: done 21. Структуриров анные типы данных: массивы. Способы объявления Массив – это упорядоченная совокупность элементов одного типа данных, имеющих одинаковое имя. Элементы массива адресуются с помощью некоторого индекса! Первый элемент имеет индекс 0 !! Количество элементов называется размерностью массива. По количеству индексов различают: - одномерные массивы (векторы – последователь ность чисел, символов); - двумерные массивы (матрицы); - трехмерные и т.д. массивы. Описание одномерного массива: тип[] имя_массива = new тип [размер]; Описание матрицы: тип[,] имя_матрицы = new [размер1, размер2]; 22. Индексация и доступ к элементам массива. Следует различать описание массива и значение его элемента при обработке (внутри программы). Элемент массива в программе записывают в виде Имя_Массива [индекс] или Имя_Матрицы [индекс1, индекс2] Пример: X[2] => x2 A[i, j] => Aij Ваll [k, i+2] => Ballk,i+2 накапливания. Индекс – это число, переменная или выражение целого типа. 23. Основные алгоритмы обработки массивов. Алгоритмы с накапливание м. Вычисление суммы и произведения нескольких чисел, а также подсчет количества в большинстве языков программирова ния выполняется постепенно, путем 1. Сумма вычисляется по формуле сумма += очередное слагаемое; Перед вычислениями начальному значению суммы нужно присвоить ноль. 2. Произведение вычисляется по формуле произведение *= очередной сомножитель; Перед вычислениями начальному значению произведения нужно присвоить 1 3. Подсчет количества выполняется по формуле, подобной формуле для вычисления суммы: количество++; Начальное значение количества должно быть = 0. 24. Основные алгоритмы обработки массивов. Нахождение минимума и максимума. При поиске минимума и максимума вводятся дом переменные min и max 1. Вначале присваивае тся значение первого числа последоват ельности, оно является текущим максимумо м/минимум ом Начиная со второго числа производиться сравнение этого числа со значением переменной, если число из массива меньше минимума, то оно становится текущим минимумом. После просмотра всех чисел последовательн ости в переменной будет находится окончательное ее значение. Если нужно вывести не только значение переменной, но и ее индекс (из лекции) 25. Массивы строк переменной длины – «рваные» массивы. Двумерный массив можно представить в виде таблицы, в которой длина каждой строки остается неизменной по всему массиву. Но в C# можно также создавать специальный тип двумерного массива, называемый ступенчатым массивом. Ступенчатый массив представляет собой массив массивов, в котором длина каждого массива может быть разной. Следовательно , ступенчатый массив может быть использован для составления таблицы из строк разной длины. Ступенчатые массивы объявляются с помощью ряда квадратных скобок, в которых указывается их размерность. Например, для объявления двумерного ступенчатого массива служит следующая общая форма: тип [][] имя массива = new тип[размер] []; где размер обозначает число строк в массиве. Память для самих строк распределяетс я индивидуально , и поэтому длина строк может быть разной. 26. Типовые алгоритмы обработки массивов. Bubble sort, линейный поиск, минмакс, больше в лекциях нет. static int[] BubbleSort(int[] array) { int temp; for (int i = 0; i < array.Length; i++) { for (int j = i + 1; j < array.Length; j++) { if (array[j] == 0) continue; if (array[i] > array[j]) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } return array; } 27. Двумерные массивы (статические и динамические) Двумерный массив представляет собой таблицу проиндексиров анных переменных. Общий синтаксис описания тип[,] имя_массива = new тип[размер_1,р азмер_2]; где размеры определяют число элементов массива по каждой размерности 28. Массивы и их связь с указателями. Адресная арифметика 29. Передача массивов в качестве параметров функции Передача одномерных массивов в качестве аргументов Инициализиров анный одномерный массив можно передать в метод. Например, следующий оператор передает массив в метод печати. 30. Концепция памяти. Операции для работы с динамической памятью. 31. Выделение и освобождение памяти под переменные, одномерные массивы. 32. Сортировка элементов массива. Алгоритм «пузырька». Bubblesort в 26 вопросе. 33. Поиск элементов массива по ключу. У нас только индексы, так что о каких ключах идет речь – не понятно. Можно в dictionary искать по ключу как в питоне, но этого в лекциях нет. 34. Array – встроенный тип C# для работы с массивом. Средства Array для поиска, сортировки, копирования массивов. } Вызывается: readtextboxwith coma(textBox1. Text) [доступ] [static] возращаемый_тип имя(список_парамет ров) { // тело функции } 36. Формальные и 35. Понятие и описание функций. Способы вызова функций. Метод создаётся вот так: public int[] readtextboxwith coma(string input) { фактические параметры функций. При обращении к функции в основной программе в скобках указываются передаваемые аргументы (если их больше одного, то через запятую): int rez = Factorial(10); Аргумент может быть непосредственным значением (например, как у нас, числом), а может быть и переменной. Такие параметры называются фактическими. Теперь обратим внимание на заголовок функции: static int Factorial (int n) В скобках описан параметр n, который принимает переданное значение. Это формальный параметр. На самом деле формальный параметр – это локальная переменная внутри функции; он существует только во время работы функции. Важно отметить, что мы передаем параметр по значению. В отличии от параметровссылок, которые позволяют менять аргумент! Поэтому формальный параметр является лишь копией фактического аргумента и любое его изменения внутри функции никак не повлияет на переданный («внешний») аргумент. 37. Передача параметров в функции по значению и по ссылке. Передача параметров в функции может осуществляться двумя способами: - по значению; - по ссылке. Первый способ называется вызовом по значению (callby-value). В этом случае значение аргумента копируется в формальный параметр метода. Следовательно, изменения, внесенные в параметр не метода, влияют на аргумент, используемый //Вызов: int a = 3, b = 5; при вызове. Swap(ref a, ref b); PS. способ Ну короче как я передачи аргумента понял, то реф - это называется вызовом мы ссылаемся на по ссылке (call-by- ту reference). Нахуя это надо - не //Функция, понятно. -- Второй } переменную. меняющая местами значения двух переменных void Swap(ref int x, ref int y) { int t = x; x = y; y = t; 38. Функции с переменным количеством параметров. Функции с переменным количеством параметров позволяют передавать некоторое количество аргументов в функцию без заранее определенного числа параметров. Для этого используется параметр params, который обозначает массив параметров. В C# существуют функции с переменным числом параметров. Это означает, что функция может принимать любое количество параметров, которое задается в момент вызова функции. Для создания функции с переменным количеством параметров нужно использовать ключевое слово `params`. Например: ``` ```csharp Также можно использовать переменное количество параметров в лямбда-выражениях: void MyFunction(params int[] args) { // здесь можно использовать args как массив } ```c# (int a, params int[] b) => { /* код функции */ } ``` ``` 39. Рекурсивные При вызове такой функции нужно указать количество и тип параметров в квадратных скобках после имени функции: функции. Это функции, которые вызывают себя сами. Пример: факториал 40. Перегрузка функций. Иногда возникает необходимость создать один и тот же метод, ```csharp MyFunction(1, 2, 3); // вызов функции с тремя параметрами int но с разным набором параметров. И в зависимости от имеющихся параметров применять определенную версию метода. Такая возможность еще называется перегрузкой методов (method overloading). И в языке C# мы можем создавать в классе несколько методов с одним и тем же именем, но разной сигнатурой. Что такое сигнатура? Сигнатура складывается из следующих аспектов: Имя метода Количество параметров Типы параметров Порядок параметров Модификатор ы параметров Но названия параметров в сигнатуру НЕ входят. Например, возьмем следующий метод: public int Sum(int x, int y) { return x + y; } У данного метода сигнатура будет выглядеть так: Sum(int, int) И перегрузка метода как раз заключается в том, что методы имеют разную сигнатуру, в которой совпадает только название метода. То есть методы должны отличаться по: Количеству параметров Типу параметров Порядку параметров Модификатора м параметров 41. Отладка и тестирование программ. Корректность и надежность программы. Корректность и устойчивость – два основных качества программной системы, без которых все остальные ее достоинства не имеют особого смысла. Понятие корректности программной системы имеет смысл только тогда, когда задана ее спецификация. В зависимости от того, как формализуется спецификация, уточняется понятие корректности. Корректность – это способность программной системы работать в строгом соответствии со своей спецификацией. Отладка – процесс, направленный на достижение корректности. Устойчивость – это способность программной системы должным образом реагировать на исключительны е ситуации. 42. Отладка и тестирование программ. Типы ошибок. Программные ошибки (bugs) Так обычно называются ошибки, которые допускает программист. Например, предположим, что приложение создается с помощью неуправляемого языка С. Если динамически выделяемая память не освобождается, что чревато утечкой памяти, появляется программная ошибка. Пользовательск ие ошибки (user errors) В отличие от программных ошибок, пользовательск ие ошибки обычно возникают из-за тех, кто запускает приложение, а не тех, кто его создает. Например, ввод конечным пользователем в текстовом поле неправильно оформленной строки может привести к генерации ошибки подобного рода, если в коде не была предусмотрена возможность обработки некорректного ввода. 43. Обработка исключительны х ситуаций с C#: блок trycatch. блоки try инкапсулируют код, формирующий часть нормальных действий программы, которые потенциально могут столкнуться с серьезными ошибочными ситуациями блоки catch инкапсулируют код, который обрабатывает ошибочные ситуации происходящие в блоке try ( удобное место для протоколирова ния ошибок). блоки try-catch не могут идти раздельно и всегда действуют совместно 44. Обработка исключительны х ситуаций с C#: блок finally. того, сгенерировано исключение или нет 45. Обработка исключительны х ситуаций с C#: использование оператора throw. класса Exception. Ну типо здесь че, можно поставить условие, и из-за него выдать исключение какое либо. Potentially useful as they say. 46. Способы Блоки finally инкапсулируют код, очищающий любые ресурсы или выполняющий другие try catch действия, которые нужно выполнить в блоке try catch. Данный код выполняется независимо от Исключение может быть сгенерировано вручную с помощью оператора throw. Ниже приведена общая форма такого генерирования: throw exceptOb; где в качестве exceptOb должен быть обозначен объект класса исключений, производного от конструирован ия программ. 1. Структурное программирова ние - это методология программирова ния, которая подразумевает разбиение программы на логические блоки, такие как функции, процедуры и модули. 2. Объектноориентированн ое программирова ние - это методология программирова ния, основанная на использовании объектов, которые содержат данные и методы для их обработки. 3. Функционально е программирова ние - это методология программирова ния, в которой основной упор делается на функции, которые принимают входные данные и возвращают результаты. 4. Императивное программирова ние - это методология программирова ния, в которой программа состоит из инструкций, которые выполняются последовательн о. 5. Декларативное программирова ние - это методология программирова ния, в которой программа описывает, что должно быть сделано, а не как это должно быть сделано 47. Модульные программы. Преимущества разработки и использования . Модули являются основой модульного программирования. Они используются для создания библиотек, которые могут включаться в различные программы (при этом совсем необязательно иметь в наличии исходный текст), а большие программы могут разделяться на логически связанные модули. Достоинства модульного программирования: упрощение процесса написания и отладки; -сокращение объема программ. Недостаток – некоторое увеличение затрат времени и памяти на оформление модулей и обращение к ним. Модули подпрограммы, а в языке С# – функции и модули. 48. Основы доказательств а правильности Основы доказательства правильности это процесс формального доказательства корректности и достоверности алгоритма или программы. Доказательство правильности заключается в доказательстве того, что алгоритм работает правильно для всех возможных входных данных. Для доказательства правильности алгоритма необходимо выполнить следующие шаги: 1. Определить спецификацию алгоритма - то есть, определить точные требования к его работе, включая входные данные, выходные данные и ограничения. 2. Разработать математическу ю модель алгоритма - это позволит сформулироват ь формальные утверждения о его работе. 3. Сформулироват ь утверждения о корректности алгоритма - это означает, что нужно доказать, что алгоритм выполняет задачу, которая соответствует его спецификации. 4. Доказать утверждения о корректности алгоритма - это требует применения математических методов и логики для доказательства, что алгоритм работает правильно для всех возможных входных данных. 5. Проверить доказательство - это позволит убедиться в правильности доказательства и убедиться в том, что алгоритм работает корректно. Доказательство правильности является важным этапом при разработке программного обеспечения и позволяет убедиться в том, что программа работает корректно и соответствует требованиям. . 49. Откуда начинается выполнение приложения С#? Точка входа – метод main() 50. Когда приложение заканчивает работу? когда метод Main завершается или когда выполнение программы прерывается по какой-либо 51. 52. 53. 54. причине (например, изза возникшей исключительно й ситуации). Сколько классов может содержать приложение С#? Столько, на сколько хватит памяти. Сколько методов Main может содержать приложение? Один. Как прочитать данные, введенные пользователем с клавиатуры? Console.ReadLin e(); В каком пространстве имен находится класс Console? Класс Console находятся в пространстве имен System и для удобства работы с ними следует указать на использование этого пространства с помощью команды using. ┤ Вывод данных на экран осуществляется с помощью метода Write() или WriteLine(). 55. Что произойдёт при необработанно м в приложении исключении? Необработанное исключение, которое достигает системы выполнения C#, вызывает немедленное, ненормальное завершение программы. Это может быть проблемой, поскольку исключение сообщается пользователю в виде сообщения или диалогового окна, содержащего стандартную информацию и технические детали, которые могут быть неправильно поняты. Во время отладки это может быть полезно, но в релизе программы на заказ это обычно считается неприемлемым. 56. Какие правила именования переменных? 1. Имя переменной должно начинаться с буквы или символа подчеркивания "_". 2. Имя переменной может содержать только буквы, цифры и символ подчеркивания "_". 3. Имя переменной не может содержать пробелов. 4. Имена переменных чувствительны к регистру, то есть переменные "myVar" и "myvar" будут различаться. 5. Имя переменной не должно быть зарезервирован ным словом языка программирова ния. 6. Имя переменной должно быть осмысленным и отражать значение переменной. 7. Длина имени переменной не должна превышать 255 символов (в некоторых языках программирова ния это ограничение может быть меньше). 57. Какие существуют способы преобразовани я типов в языке C#? Явные и неявные. В вопросе 98 о них написано. 58. Перечислите основные группы операторов, выделив их характерные особенности. 59. Базовые типы данных, переменные целочисленная переменная n типа int sbyte tiny; // целочисленная переменная tiny типа sbyte 60. Тип Прежде чем использовать переменную, ее нужно объявить. Присвоить – значит установить текущее значение переменной. Например, int n; // string. Программы работы с переменными типа string С точки зрения программирования этот тип данных относится к числу самых важных в C#. Этот тип определяет и поддерживает символьные строки в кодировке Unicode (1 символ – 2 байта). В целом ряде других языков программирования строка представляет собой массив символов. А в C# строки относятся к числу ссылочных типов, т.е. фактически являются объектами класса String, которые, однако, имеют свои особенности. Основные методы строк Основная функциональность класса String раскрывается через его методы, среди которых можно выделить следующие: Compare: сравнивает две строки с учетом текущей культуры (локали) пользователя CompareOrdinal: сравнивает две строки без учета локали Contains: определяет, содержится ли подстрока в строке Concat: соединяет строки CopyTo: копирует часть строки, начиная с определенного индекса в массив EndsWith: определяет, совпадает ли конец строки с подстрокой Format: форматирует строку IndexOf: находит индекс первого вхождения символа или подстроки в строке Insert: вставляет в строку подстроку Join: соединяет элементы массива строк Split: разделяет одну строку на массив строк начальные и конечные пробелы из строки Substring: извлекает из строки подстроку, начиная с указанной позиции Разберем работу этих методов. ToLower: переводит все символы строки в нижний регистр char, дайте характеристик у ToUpper: переводит LastIndexOf: находит индекс последнего вхождения символа или подстроки в строке Replace: замещает в строке символ или подстроку другим символом или подстрокой 61. Тип все символы строки в верхний регистр Trim: удаляет Тип char в языке программирова ния C# является целочисленным типом данных, который используется для хранения одного символа. Он занимает 1 байт памяти и может содержать любой символ из таблицы ASCII или расширенной таблицы Unicode. Char также может использоваться для хранения целочисленных значений в диапазоне от 128 до 127 или от 0 до 255, в зависимости от того, используется ли знаковый или беззнаковый char. используется для перебора элементов в массивах, списках и других коллекциях данных. 62. Оператор for Синтаксис оператора for выглядит следующим образом: Оператор for это циклическая конструкция в языке программирова ния, которая позволяет выполнить определенный блок кода несколько раз. Он for (инициализация ; условие; итерация) { // блок кода, который нужно выполнить } Инициализация выполняется один раз в начале цикла и используется для объявления переменных и установки начальных значений. Условие проверяется перед каждой итерацией цикла. Если условие истинно, то блок кода выполняется, если ложно цикл прерывается. Итерация выполняется после каждого прохода цикла и позволяет изменять значения переменных. Пример использования оператора for: for (int i = 0; i < 10; i++) { System.out.printl n("Значение i: " + i); } В этом примере мы объявляем переменную i со значением 0 в блоке инициализации. Условие гласит, что цикл будет выполняться, пока i меньше 10. После каждой итерации переменная i увеличивается на 1. Результат выполнения кода будет выводить значения переменной i от 0 до 9 63. Размер и диапазон целочисленны х типов в C# 64. Понятие операции, выражения, оператора в С#. Операция в C# - это действие, которое выполняется над одним или несколькими операндами (значениями). Например, операция сложения (+), вычитания (-), умножения (*), деления (/) и т.д. Операции могут быть арифметически ми, логическими, сравнениями, присваивания и т.д. Они используются для выполнения различных задач в программирова нии, таких как вычисления, проверки условий, присваивания значений переменным и т.д Конструкция "выражение" в C# относится к синтаксической конструкции, которая может быть вычислена в значение. Выражение может быть составлено из переменных, операторов, методов и литералов. Оператор в C# - это символ, который выполняет определенную операцию над одним или несколькими операндами. Операторы могут быть арифметически ми (например, сложение, вычитание, умножение), логическими (например, И, ИЛИ, НЕ), сравнения (например, равно, больше, меньше) и т.д. Операторы могут также использоваться для управления потоком выполнения программы (например, ifelse, switchcase) и для работы с указателями и адресами памяти (например, & и *). арифметическ ие операции. i++, i - - 68. Побитовые 66. Операции присваивания. Виды операции. 67. Операции 65. Основные инкремента и декремента. или булевские операции. Побитовые операции - это операции, которые выполняются над отдельными битами чисел. Они включают в себя операции И (&), ИЛИ (|), исключающее ИЛИ (^), сдвиг влево (<<) и сдвиг вправо (>>). Булевские операции - это операции, которые выполняются над булевыми значениями (истина или ложь). Они включают в себя операции И (&&), ИЛИ (||) и НЕ (!). Обе эти группы операций широко используются в программирова нии для выполнения различных задач, таких как манипуляции с битами, проверка условий, управление потоком выполнения программы и т.д. 69. Объявление и инициализаци я переменных. float С_X, С_Y; // вещественные переменные С_X и С_Y типа float них Круто. 70. Константы. Переменная описывается следующим образом: тип имя переменной; _ Например, int n; // целочисленная переменная n типа int sbyte tiny; // целочисленная переменная tiny типа sbyte double x; // вещественная переменная x типа double short A1, A2; // целочисленные переменные A1, A2 типа short Например, если нужно присвоить переменной значение, полученное из выражения, можно использовать следующий код: `int age = ageValue;` Здесь `ageValue` это выражение, возвращающее значение типа `int`. Такое ощущение, что я уже раза 4 писал про переменные, ах да, там еще 1 или два вопроса про Способы объявления констант в С#. Константа - это переменная, значение которой не изменяется во время выполнения программы. Способы объявления констант в С#: с помощью ключевого слова const с помощью ключевого слова readonly в сочетании с модификатором static В C# константы объявляются с использованием ключевого слова const. Константа может быть объявлена как с типом, так и без него. Если тип не указан, то по умолчанию используется тип int. Примеры объявления констант: const int MAX_AGE = 180; // константа целого типа const string FAVORITE_COLOR = "blue"; // константа строкового типа const byte WEIGHT_IN_P OUNDS = 150; // константа 71. Литералы. Целочисленны е, вещественные, символьные литералы. Литералы — это явно заданные значения в коде программы — константы определенного типа, которые находятся в коде в момент запуска целочисленные 11; вещественные 0.39; символьные ‘A’ Литералы представляют неизменяемые значения (иногда их еще называют константами). Литералы можно передавать переменным в качестве значения. Литералы бывают логическими, целочисленным и, вещественными , символьными и строчными. И отдельный литерал представляет ключевое слово null. Логические литералы Есть две логических константы - true (истина) и false (ложь) Целочисленны е литералы Целочисленные литералы представляют положительные и отрицательные целые числа, например, 1, 2, 3, 4, -7, -109. Целочисленные литералы могут быть выражены в десятичной, шестнадцатери чной и двоичной форме. С целыми числами в десятичной форме все должно быть понятно, так как они используются в повседневной жизни Вещественные литералы Вещественные литералы представляют дробные числа. Этот тип литералов имеет две формы. Первая форма вещественные числа с фиксированной запятой, при которой дробную часть отделяется от целой части точкой. Например: Символьные литералы Символьные литералы представляют одиночные символы. Символы заключаются в одинарные кавычки. Специальную группу представляют управляющие последовательн ости Управляющая последовательн ость представляет символ, перед которым ставится слеш. И данная последовательн ость интерпретирует ся определенным образом. Наиболее часто используемые последовательн ости: '\n' - перевод строки Например: // Вывод на консоль Console.WriteLi ne("Hello World!"); '\t' - табуляция '\\' - слеш 72. Реализация ввода-вывода в С#. Ввод-вывод в C# осуществляется с помощью классов Console и File. Класс Console используется для вывода информации на консоль и чтения данных с консоли. // Чтение данных с консоли string input = Console.ReadLi ne(); Класс File используется для работы с файлами. Например, для чтения данных из файла: // Вывод данных на консоль Console.WriteLi ne(text); Для записи данных в файл используется метод File.WriteAllTex t(): // Запись данных в файл string data = "Hello World!"; File.WriteAllTex t("file.txt", data); 73. Условие // Чтение данных из файла string text = File.ReadAllTex t("file.txt"); в программиров ании. Простые и составные условия. Простым условием называется логическое выражение, составленное из двух арифметически х выражений или двух величин, связанных одним из знаков отношений:< меньше> больше<= меньше или равно>= больше или равно<> - не равно= - равно. Например, простыми отношениями являются следующие: xy>10 Составные условия условия, состоящие из двух или более простых условий, соединенных с помощью логических операций and (и), or (или), not (не). Простые условия при этом заключаются в круглые скобки. Примеры составных условий: (a>5) and (a<13) 74. Операции отношения (сравнения), логические операции. Операции отношения используются для сравнения значений переменных и констант. Всего имеется 6 операций отношения: == (равно), != (не равно), < (меньше), > (больше), <= (меньше или равно), >= (больше или равно). С# имеются логические операции:& конъюнкция (логическое И); | - дизъюнкция (логическое или); ! логическое отрицание; ^ взаимоисключа ющее или. Семантика этих операций известна из курса математической логики. Кроме того в. С# определены две условные (conditional) логические бинарные операции:&& условная конъюнкция (условное И); || условная дизъюнкция (условное или). В выражении х&&у значение у не вычисляется, если х имеет значение false. 75. Условный оператор. 76. Условная операция С#. Что в то происходит, если удовлетворяет условию. if (эта херня == задолбала) { } else Тернарная операция Тернарную операция также позволяет проверить некоторое условие и в зависимости от его истинности выполнить некоторые действия. Она имеет следующий синтаксис: 1 [первый операнд - условие] ? [второй операнд] : [третий операнд] Здесь сразу три операнда. В зависимости от условия тернарная операция возвращает второй или третий операнд: если условие равно true, то возвращается второй операнд; если условие равно false, то третий. Например: int x=3; int y=2; int z = x < y ? (x+y) : (x-y); Console.WriteLi ne(z); // 1 Здесь первый операнд (то есть условие) представляет выражение x < y. Если оно равно true, то возвращается второй операнд - (x+y), то есть результат операции сложения. Если условие равно false, то возвращается третий операнд - (x-y). Результат тернарной операции (то есть второй или третий операнд в зависимости от условия) присваивается переменной z. 77. Оператор множественно го выбора switch () в С#. Смотрим 13 вопрос 78. Особенности использования оператора break. В языке C# оператор break имеет два основных направления применения: ● в операторах цикла оператор break используетс я для завершения циклическог о процесса (прерывание работы цикла). Такое действие необходимо , кода нужно прервать выполнение цикла в зависимости от некоторого условия; ● в операторе выбора switch применение оператора break нужно для реализации выхода из данного оператора. элементы которой надо перебрать. 79. Объясните принцип работы цикла foreach. Цикл foreach предназначен для перебора набора или коллекции элементов. Его общее определение: foreach(тип_данных переменная in коллекция) { // действия цикла } После оператора foreach в скобках сначала идет определение переменной. Затем ключевое слово in и далее коллекция, При выполнении цикл последовательно перебирает элементы коллекции и помещает их в переменную, и таким образом в блоке цикла мы можем выполнить с ними некоторые действия. Например, возьмем строку. Строка по сути - это коллекция символов. И .NET позволяет перебрать все элементы строки - ее символы с помощью цикла foreach. foreach(char "Tom") { c in Console.WriteLine(c); } Здесь цикл foreach пробегается по всем символам строки "Tom" и каждый символ помещает в символьную переменную c. В блоке цикла значение переменной c выводится на консоль. Поскольку в строке "Tom" три символа, то цикл выполнится три раза. Консольный вывод программы: T o m 80. Преобразовани е встроенных типов данных. Операция преобразования типов предполагает указание в скобках того типа, к которому надо преобразовать значение: (тип_данных_в_кото рый_надо_преобразо вать)значение_для_п реобразования; Так, изменим предыдущий пример, применив операцию преобразования типов: byte a = 4; byte b = (byte)(a + 70); 81. Явные (explicit) и неявные (implicit) преоб разования. Использование ключевого слова checked. Неявные преобразования В случае с расширяющими преобразованиями компилятор за нас выполнял все преобразования данных, то есть преобразования были неявными (implicit conversion). Такие преобразования не вызывают каких-то затруднений. Тем не менее стоит сказать пару слов об общей механике подобных преобразований. sbyte a = 4; // 0000100 short b = a; // 000000000000100 Явные преобразования При явных преобразованиях (explicit conversion) мы сами должны применить операцию преобразования (операция ()). Суть операции преобразования типов состоит в том, что перед значением указывается в скобках тип, к которому надо привести данное значение: int a = 4; int b = 6; byte c = (byte)(a+b); 82. Константы. Ключевое слово var. Константы Отличительной особенностью переменных является то, что мы можем изменить их значение в процессе работы программы. Но, кроме того, в C# есть константы. Константа должна быть обязательно инициализирована при определении, и после определения значение константы не может быть изменено Константы предназначены для описания таких значений, которые не должны изменяться в программе. Для определения констант используется ключевое слово const, которое указывается перед типом константы: const string NAME = "Tom"; // определяем константу Так, в данном случае определена константа NAME, которая хранит строку "Tom". Нередко для название констант используется верхний регистр, но это не более чем условность. При использовании констант надо помнить, что объявить мы их можем только один раз и что к моменту компиляции они должны быть определены. Так, в следующем случае мы получим ошибку, так как константе не присвоено начальное значение: const string NAME; // ! Ошибка константа NAME не инициализирована Локальные переменные можно объявлять без указания конкретного типа. Ключевое слово var указывает, что компилятор должен вывести тип переменной из выражения справа от оператора инициализации. Выведенный тип может быть встроенным, анонимным, определяемым пользователем либо типом, определяемым в библиотеке классов .NET. Важно понимать, что ключевое слово var не означает "variant" и не означает, что переменная является слабо типизированной или имеет позднее связывание. Он указывает только на то, что компилятор определяет и назначает наиболее подходящий тип. Делегаты (delegate) Насколько я понял, то ссылочные типы хранятся в хипе, а их ссылка(поинтер) в стеке. 84. Оператор «if- else». Уже был несколько раз, мне лень ещё раз писать. 83. Ссылочные типы Ссылочные типы: Тип object Тип string 85. Методы (функции) класса String для работы со строками в С #. Классы (class) 86. Методы Интерфейсы (interface) IsNullOrEmpty () , IsNullOrWhite Space( ), Compare() IsNullOrEmpty() проверяет строку на null или если она пустая. Возвращает bool. IsNullOrWhiteSpace ( ) Указывает, имеет ли указанная строка значение null, является ли она пустой строкой или строкой, состоящей только из символовразделителей. стринг в больших буквах(upper case) ToLower() возвращает весь стринг в маленьких буквах(lower case) 87. Методы ToUpper() и ToLower(), методы StartsWith() и EndsWith(), Contains(), IndexOf() ToUpper() возвращает весь какоето_название.StartsW ith(здесь что ищем) чекает начало стринга, и возвращает буль если есть то, что мы ищем. EndsWith() то же самое, только в конце Contains() - чекает, есть ли char или string в нужном стринге В C# метод indexOf() является строковым методом. Этот метод используется для нахождения основанного на нуле индекса первого вхождения указанного символа или строки в текущем экземпляре строки. Метод возвращает -1, если символ или строка не найдены. String Insert(), Remove(), Substring(), Replace() modified = original.Insert(3, " "); ий", "плохой"); Console.WriteLine(t ext); Remove() все в Удаляет стринге // плохой день с определенного text индекса text.Replace("о", text 88. Методы text.Replace("хорош value); = “Хороший = ""); день Console.WriteLine(t text = text.Remove(0, ext); // плхй день 2); Console.WriteLine(te Substring() xt); // роший день string text = "Хороший день"; Insert() Возвращает новую строку, в которой указанная строка вставляется в указанной позиции индекса в данном экземпляре. public string Insert Replace() заменяет в // обрезаем начиная стринге с третьего символа (int startIndex, string text одни символы на другие string text text = = text.Substring(2); // результат "роший "хороший день"; день" = Console.WriteLine(te xt); // обрезаем сначала до последних двух символов text = text.Substring(0, text.Length - 2); // результат "роший де" Console.WriteLine(te xt); 89. Преобразовани е строки в массив символов. Методы ToCharArray(), Split() ToCharArray(), Копирует знаки данного экземпляра в массив знаков Юникода. public char[] ToCharArray (int startIndex, int length); Параметры startIndex Int32 Начальная позиция подстроки в данном экземпляре. length Int32 Длина подстроки в данном экземпляре. Возвращаемое значение Char[] Массив знаков Юникода, элементами которого являются length знаков данного экземпляра начиная с позиции startIndex. s.Split(' ', '.'); foreach (var sub in subs) Split(), Возвращает строковый массив, содержащий подстроки данного экземпляра, разделенные элементами заданной строки или массива знаков Юникода. } string s = "You win some. You lose some."; string[] subs = { Console.WriteLi ne($"Substring: {sub}"); // This example produces the following output: // // Substring: You // Substring: win // Substring: some // Substring: // Substring: You // Substring: lose // Substring: some // Substring: 90. Понятие Конструктора, инициализаци и. Конструкторы – функции, автоматически вызываемые при инициализации объекта. Имя конструктора совпадает с именем класса. Конструкторы — это методы, которые позволяют инициализировать класс, тем самым создают из класса объект, размещая его в памяти. Конструктор — это обычная (по структуре) функция, получающая на свой вход данные, которые присваиваются полям класса. Из пустого шаблона за счет задания полей получается объект. Операторы, которые присваивают значения полям класса. Если поля в классе описаны как string type, string name, float speed, то в теле должны быть операторы: Type=Type; name=Name; speed=Speed; То есть в итоге конструктор класса MyCar будет иметь вид: MyCar(string Type, string Name, float Speed) { type=Type; name=Name; speed=Speed; } Если мы теперь из класса хотим создать конкретный объект, например автомобиль Николая, то должны записать: MyCar Nik_car = new MyCar("Porshe", “Nikolai", 250.0); По этому оператору конструктор создаст объект с именем Nik_car, оператор new разместит объект (или — экземпляр класса MyCar) в динамической куче и выдаст адрес начала объекта в этой куче. Адрес положен полочку переменной Nik_car. будет на для самом поле класса. 92. Свойство в С#. 93. Принципы типизации данных. Иерархия простых типов данных. 91. Ключевое слово this. В С# возможно использование ключевого слова this для обеспечения доступа к текущему экземпляру класса. Это может понадобиться во избежание неоднозначности контекста в том случае, например, когда имя входящего параметра совпадает с именем поля. Короче эта фигня нужна для того, чтобы менять что либо не в конструкторе, а в 94. Стандартные типы данных. Особенности выбора типа. 95. Внутреннее представление данных типа int 96. Внутреннее представление данных c плавающей точкой 97. Явное и неявное преобразовани е типов. Правила преобразовани я типов. В C# можно выполнять следующие виды преобразований : Неявные преобразования Не требуется никакого специального синтаксиса, поскольку преобразование безопасно для типов и данные не теряются. Примерами могут служить преобразования от меньшего к большему целому типу. int num = 2147483647; long bigNum = num; Явные преобразования (приведения) Для явных преобразований необходим оператор приведения. Приведение требуется, когда при преобразовании может быть потеряна информация, или когда преобразование может завершиться неудачей по другим причинам. К типичным примерам относится числовое преобразование в тип, который имеет меньшую точность или меньший диапазон значений. (новый_тип)имя _переменной double x = 3.25; int y = (int)x; // y =3 98. Переменные (объявление, инициализаци я, присвоение). Чтобы объявить лок переменную, укажите её тип и имя. В одной конструкции можно объявить несколько локальных переменных. Область видимости переменной часть кода, в пределах которого доступна данная переменная. Чтобы инициализиров ать лок переменную нужно дать начальное значение Чтобы присвоить испть = 99. Константы. Специальные символы. Квалификатор const. Константы — это постоянные значения, которые известны во время компиляции и не изменяются во время выполнения программы Специальные символы — это стандартные контекстнозависимые символы, которые изменяют элемент программы (строковый литерал, идентификатор или имя атрибута), к которому они добавляются. C# поддерживает следующие специальные символы: ● @, символ буквально го идентифи катора. ● $, символ интерпол ируемой строки. Квалифик атор const запрещает любые изменени я переменн ой после ее инициали зации 100. Что такое платформа MS.NET? Каковы её преимущества ? MS.NET Framework — это технология, которая поддерживает создание и выполнение веб-служб и приложений Windows Её преимущества: 1. Полная поддержка ООП 2.Языковая независимость 3.Общая система типов 4.Безопасность кода 5.Среда .NET имеют встроенную поддержку и создание webслужб, динамических web-сайтов 101. Перечислите основные понятия платформы .NET. 1.Common Language Runtime (CLR) виртуальная машина, которая управляет выполнением кода на языках .NET и обеспечивает безопасность и управление памятью. 2. Framework Class Library (FCL) библиотека классов, которая содержит множество готовых компонентов для разработки приложений, таких как работа с файлами, сетевыми протоколами, базами данных и т.д. 3. Common Type System (CTS) - система типов, которая определяет правила для определения и использования типов данных в .NET. 4. Common Language Specification (CLS) - набор правил, которые гарантируют совместимость кода на различных языках .NET. 5. Intermediate Language (IL) промежуточны й язык, на котором компилируется код на языках .NET перед выполнением в CLR. 6. Just-In-Time (JIT) компиляция процесс компиляции ILкода в машинный код во время выполнения приложения. 7. Assembly единица развертывания приложения в .NET, которая содержит ILкод, метаданные и ресурсы. 8. Namespace логическая группировка классов и других типов в .NET. 9. Attribute механизм метаданных, который позволяет добавлять дополнительну ю информацию к типам и членам классов. 10. Delegate тип данных, который представляет ссылку на метод и используется для реализации событий и обратных вызовов. 102. Охарактеризу йте компоненты MS.NET Framework. MS.NET Framework - это программная платформа, которая включает в себя несколько компонентов: 1. Common Language Runtime (CLR) исполняющая среда для выполнения кода, написанного на языках программирова ния, таких как C#, VB.NET и F#. 2. Class Library набор библиотек классов, предоставляющ их различные функции и возможности для разработки приложений. 3. ASP.NET платформа для создания вебприложений на языках программирова ния, таких как C# и VB.NET. 4. ADO.NET набор библиотек для работы с базами данных и выполнения запросов. 5. Windows Communication Foundation (WCF) платформа для создания распределенны х приложений, которые могут взаимодействов ать через сеть. 6. Windows Presentation Foundation (WPF) платформа для создания графических интерфейсов пользовательск ого интерфейса (GUI) для Windowsприложений. 7. Windows Workflow Foundation (WF) платформа для создания рабочих процессов и автоматизации бизнеспроцессов. 8. LINQ - язык запросов для работы с коллекциями данных и базами данных. Все эти компоненты MS.NET Framework предназначены для упрощения и ускорения процесса разработки приложений, а также для обеспечения их высокой производительн ости и безопасности. 103. Что такое общеязыковая среда выполнения? Какие ее основные сервисы? Общеязыковая среда выполнения (Common Language Runtime) исполняющая среда для байткода CIL(Common Intermediate Language«высо коуровневый ассемблер» виртуальной машины .NET. Промежуточны й язык, разработанный фирмой Microsoft для платформы .NET Framework. JITкомпилятор CIL является частью CLR общей среды выполнения программ, написанных на языках), в которой компилируются программы, написанные на NET совместимых языках программирова ния. Сервисы: Повышает производительн ость Реализует виртуальную среду выполнения Определённая стандартная спецификация общеязыковой структуры 104. Перечислите основные классы библиотеки .NET Framework. Некоторые из основных классов библиотеки .NET Framework включают: 1. System.String - класс для работы со строками. 2. System.IO классы для работы с файлами и директориями. 3. System.Collectio ns - классы для работы с коллекциями данных, такими как списки, словари и множества. 4. System.Threadin g - классы для работы с потоками и асинхронными операциями. 5. System.Net классы для работы с сетевыми протоколами и соединениями. 6. System.Xml классы для работы с XMLданными и документами. 7. System.Data классы для работы с базами данных и выполнения запросов. 8. System.Web классы для работы с вебприложениями и вебсервисами. 9. System.Security - классы для работы с безопасностью приложений и данных. 10. System.Diagnost ics - классы для работы с логированием, отладкой и профилировани ем приложений. 105. Объектноориентированн ое программирова ние. Такой подход к написанию программы основывается на объектах, а не на функциях и процедурах. Ставит в центр внимания объекты, а не действия, данные, логику. класса Person, который, в свою очередь, называется базовым классом или родителем (или суперклассом): 106. Наследование Наследование (inheritance) является одним из ключевых моментов ООП. Благодаря наследованию один класс может унаследовать функциональность другого класса. Пусть у нас есть следующий класс Person, который описывает отдельного человека: Но вдруг нам потребовался класс, описывающий сотрудника предприятия - класс Employee. Поскольку этот класс будет реализовывать тот же функционал, что и класс Person, так как сотрудник - это также и человек, то было бы рационально сделать класс Employee производным (или наследником, или подклассом) от После двоеточия мы указываем базовый класс для данного класса. Для класса Employee базовым является Person, и поэтому класс Employee наследует все те же свойства, методы, поля, которые есть в классе Person. Единственное, что не передается при наследовании, это конструкторы базового класса с параметрами. Таким образом, наследование реализует отношение is-a (является), объект класса Employee также является объектом класса Person: И поскольку объект Employee является также и объектом Person, то мы можем так определить переменную: Person p = new Employee(). По умолчанию все классы наследуются от базового класса Object, даже если мы явным образом не устанавливаем наследование. Поэтому выше определенные классы Person и Employee кроме своих собственных методов, также будут иметь и методы класса Object: ToString(), Equals(), GetHashCode() и GetType(). Все классы по умолчанию могут наследоваться. Однако здесь есть ряд ограничений: Не поддерживается множественное наследование, класс может наследоваться только от одного класса. При создании производного класса надо учитывать тип доступа к базовому классу - тип доступа к производному классу должен быть таким же, как и у базового класса, или более строгим. То есть, если базовый класс у нас имеет тип доступа internal, то производный класс может иметь тип доступа internal или private, но не public. Однако следует также учитывать, что если базовый и производный класс находятся в разных сборках (проектах), то в этом случае производный класс может наследовать только от класса, который имеет модификатор public. Если класс объявлен с модификатором sealed, то от этого класса нельзя наследовать и создавать производные классы. Например, следующий класс не допускает создание наследников: Нельзя унаследовать класс от статического класса. 107. Ключевое слово base Ключевое слово base Теперь добавим в наши классы конструкторы: Класс Person имеет конструктор, который устанавливает свойство Name. Поскольку класс Employee наследует и устанавливает то же свойство Name, то логично было бы не писать по сто раз код установки, а както вызвать соответствующий код класса Person. К тому же свойств, которые надо установить в конструкторе базового класса, и параметров может быть гораздо больше. С помощью ключевого слова base мы можем обратиться к базовому классу. В нашем случае в конструкторе класса Employee нам надо установить имя и компанию. Но имя мы передаем на установку в конструктор базового класса, то есть в конструктор класса Person, с помощью выражения base(name). Employee уберем определение конструктора: 108. Конструкторы в производных классах Конструкторы не передаются производному классу при наследовании. И если в базовом классе не определен конструктор по умолчанию без параметров, а только конструкторы с параметрами (как в случае с базовым классом Person), то в производном классе мы обязательно должны вызвать один из этих конструкторов через ключевое слово base. Например, из класса В данном случае мы получим ошибку, так как класс Employee не соответствует классу Person, а именно не вызывает конструктор базового класса. Даже если бы мы добавили какойнибудь конструктор, который бы устанавливал все те же свойства, то мы все равно бы получили ошибку: То есть в классе Employee через ключевое слово base надо явным образом вызвать конструктор класса Person: 109. Порядок вызова конструктора При вызове конструктора класса сначала отрабатывают конструкторы базовых классов и только затем конструкторы производных. Например, возьмем следующие классы: выполнение конструктору Person(string name) В итоге получаем следующую выполнений. мы цепь Вначале вызывается конструктор Employee(string name, int age, string company). Он делегирует выполнение конструктору Person(string name, int age) Вызывается конструктор Person(string name, int age), который сам пока не выполняется и передает Вызывается конструктор Person(string name), который передает выполнение конструктору класса System.Object, так как это базовый по умолчанию класс для Person. Выполняется конструктор System.Object.Object (), затем выполнение возвращается конструктору Person(string name) Выполняется тело конструктора Person(string name), затем выполнение возвращается конструктору Person(string int age) name, Выполняется тело конструктора Person(string name, int age), затем выполнение возвращается конструктору Employee(string name, int age, string company) Выполняется тело конструктора Employee(string name, int age, string company). В итоге создается объект Employee 110. Преобразовани я объектов классов Допустим, у нас есть следующая иерархия классов: следующем коде переменная person хранит ссылку на объект Employee: 111. Нисходящие преобразовани я. Downcasting Но кроме восходящих преобразований от производного к базовому типу есть нисходящие преобразования или downcasting - от базового типа к производному. Например, в И может возникнуть вопрос, можно ли обратиться к функционалу типа Employee через переменную типа Person. Но автоматически такие преобразования не проходят, ведь не каждый человек (объект Person) является сотрудником предприятия (объектом Employee). И для нисходящего преобразования необходимо применить явное преобразование, указав в скобках тип, к которому нужно выполнить преобразование: Рассмотрим некоторые примеры преобразований: В первом случае переменной obj присвоена ссылка на объект Employee, поэтому мы можем преобразовать объект obj к любому типу который располагается в иерархии классов между типом object и Employee. 112. Восходящие Если нам надо обратиться к какимто отдельным свойствам или методам объекта, то нам необязательно присваивать преобразованный объект переменной: преобразовани я. Upcasting Объекты производного типа (который находится внизу иерархии) в то же время представляют и базовый тип. Например, объект Employee в то же время является и объектом класса Person. Что в принципе естественно, так как каждый сотрудник (Employee) является человеком (Person). И мы можем написать, например, следующим образом: В данном случае переменной person, которая представляет тип Person, присваивается ссылка на объект Employee. Но чтобы сохранить ссылку на объект одного класса в переменную другого класса, необходимо выполнить преобразование типов - в данном случае от типа Employee к типу Person. И так как Employee наследуется от класса Person, то автоматически выполняется неявное восходящее преобразование преобразование к типу, которые находятся вверху иерархии классов, то есть к классу. базовому В итоге переменные employee и person будут указывать на один и тот же объект в памяти, но переменной person будет доступна только та часть, которая представляет функционал типа Person. Person bob = new Client("Bob", "ContosoBank"); // преобразование от Client к Person Здесь переменная bob, которая представляет тип Person, хранит ссылку на объект Client, поэтому также выполняется восходящее неявное преобразование от производного класса Client к базовому типу Person. Восходящее неявное преобразование будет происходить и в следующем случае: Подобным образом поизводятся и другие восходящие преобразования: Так как тип object базовый для всех остальных типов, то преобразование к нему будет производиться автоматически. 113. Способы преобразовани й Во-первых, можно использовать ключевое слово as. С помощью него программа пытается преобразовать выражение к определенному типу, при этом не выбрасывает исключение. В случае неудачного преобразования выражение будет содержать значение null: Стоит отметить, что переменная employee здесь определяется не просто как переменная Employee, а именно Employee? - после названия типа ставится вопросительный знак. Что указывает, что переменная может хранить как значение null, так и значение Employee. Второй способ заключается в проверке допустимости преобразования с помощью ключевого слова is: значение is тип Если значение слева от оператора представляет тип, указаный справа от оператора, то оператор is возвращает true, иначе возвращается false. Причем оператор is позволяет автоматически преобразовать значение к типу, если это значение представляет данный тип. Например: объект employee как значение типа Employee. Выражение if (person is Employee employee) проверяет, является ли переменная person объектом типа Employee. И если person является объектом Employee, то автоматически преобразует значение переменной person в тип Employee и преобразованное значение сохраняет в переменную employee. Далее в блоке if мы можем использовать Однако, если person не является объектом Employee, как в данном случае, то такая проверка вернет значение false, и преобразование не сработает. Оператор is также можно применять и без преобразования, просто проверяя на соответствие типу: