Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


В отличие от оператора for оператор while никак не изменяет значения пере-



переменной цикла, поэтому мы должны позаботиться об этом сами.

Перед тем как приступить к выполнению цикла, мы устанавливаем начальное зна-

значение параметра цикла i, равное нулю. После выполнения тела цикла мы сами изме-

изменяем значение параметра цикла, увеличивая его на единицу.

Цикл будет прерван, как только значение переменной i превысит 10.

В цикле while можно использовать описанные ранее операторы прерывания цик-

цикла break и возобновления цикла continue.

Следующий цикл будет выполняться бесконечно:

while(true)

{

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

Оператор do

Оператор do используется вместе с ключевым словом while. При этом условие за-

завершения цикла проверяется после выполнения его тела:

i = 0;

do

{

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

i + +;

} while(i < 10) ;

 

Оператор foreach

Для обработки таких типов данных, как массивы и контейнеры, язык С# предлагает

очень удобный оператор foreach, для которого нет аналога в языках программиро-

программирования С и C++.

Так как изучение этих типов данных еще впереди, в этой главе мы дадим упрощен-

упрощенное определение массива и приведем простейший пример программы, работающей

с массивами при помощи операторов for и foreach.

Итак, мы будем считать массив набором упорядоченных объектов, каждый из ко-

которых имеет свой номер, или индекс. Первый элемент массива имеет индекс 0, вто-

второй — 1 и т. д.

Массив целых чисел со знаком объявляется следующим образом:

int[] nums;

Пара квадратных скобок указывает на то, что переменная nums является массивом.

Прежде чем пользоваться массивом, его необходимо создать, указав максимальное

количество объектов, которые могут в нем храниться. Вот как объявляется и создается

массив переменных типа int:

int[] nums;

nums = new int[10];

Созданный массив инициализируется значениями по умолчанию. Для числовых

массивов в качестве такого значения используется 0.

Чтобы записать в элемент массива с заданным номером какое-либо значение, необ-

необходимо указать индекс этого элемента в квадратных скобках.

Ниже мы в цикле инициализируем массив, записывая в его элементы числа от 0

до 9, причем в нулевой элемент массива записывается значение 0, в первый — значе-

значение 1 и т. д.:

for(i =0; i < 10; i++)

nums[i] = i;

Чтобы отобразить содержимое всех ячеек массива, можно использовать обычный

цикл for:

for(i = 0; i < 10;

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

Здесь мы последовательно выводим на консоль все значения, хранящиеся в массиве.

Хотя на первый взгляд этот способ обработки всех элементов массива достаточно

прост, ему присущи некоторые недостатки. Например, нам нужно объявлять и ини-

инициализировать переменную цикла (применяемую в роли индекса массива), а затем

увеличивать ее значение при каждой итерации. При этом нужно следить, чтобы значе-

значение переменной цикла не превысило размер массива, иначе возникнет исключение.

Оператором f oreach пользоваться намного проще:

foreach(int current in nums)

System.Console.Write("{0} ", current);

В скобках после ключевого слова f oreach мы объявляем переменную current

типа int, которой при каждой итерации будут последовательно присваиваться все

значения массива nums. Имя этого массива указывается после ключевого слова in.

Таким образом, нам не нужна переменная цикла и, следовательно, не нужно ее

инициализировать, инкрементировать и проверять, не вышло ли значение индекса

массива за допустимые пределы.

Оператор foreach сделает все за нас. Он последовательно присвоит значение

всех элементов массива переменной current, а нам останется только выводить при

каждой итерации значение этой переменной на консоль.

 


 

10. Виды циклов в языке С#. Синтаксис, объявление, применение циклов в языке С#.

делегат — это тип, который определяет подпись метода и его можно связать с любым методом с совместимой подписью. Метод можно запустить (или вызвать) с помощью делегата. Делегаты используются для передачи методов в качестве аргументов к другим методам. Обработчики событий — это ничто иное, как методы, вызываемые с помощью делегатов. Создание пользовательского метода и класса, например элемента управления Windows, может вызывать метод при возникновении определенного события.

 

public delegate int PerformCalculation(int x, int y);

Делегаты имеют следующие свойства.

· Делегаты похожи на указатели функций в C++, но являются строго типизированными.

· Делегаты допускают передачу методов в качестве параметров.

· Делегаты можно использовать для задания функций обратного вызова.

· Делегаты можно связывать друг с другом; например, несколько методов можно вызвать по одному событию.

· Точное соответствие методов подписи делегата не требуется. Дополнительные сведения см. в разделе Covariance and ContravarianceКовариация и контрвариация в делегатах (руководство по программированию в C#).

· В C# версии 2.0 представлена концепция анонимных методов, которые позволяют передавать блоки кода в виде параметров вместо использования отдельно определенного метода. В C# 3.0 для краткой записи встроенных блоков кода введены лямбда-выражения. В результате компиляции как анонимных методов, так и лямбда-выражений (в определенном контексте) получаются типы делегатов. В настоящее время эти функции объединяются под одним названием — анонимные функции. Дополнительные сведения о лямбда-выражениях см. в разделе Анонимные функции (Руководство по программированию в C#).

· public delegate void Del(string message); // Create a method for a delegate.public static void DelegateMethod(string message){ System.Console.WriteLine(message);} // Instantiate the delegate.Del handler = DelegateMethod; // Call the delegate.handler("Hello World");

 

 

Типы делегатов являются производными от класса Delegate в платформе .NET Framework. Типы делегатов являются запечатанными — от них нельзя наследовать, а от Delegate нельзя создавать производные пользовательские классы. Поскольку созданный экземпляр делегата является объектом, его можно передавать как параметр или назначать свойству. Это позволяет методу принимать делегат в качестве параметра и вызывать делегат впоследствии. Эта процедура называется асинхронным обратным вызовом и обычно используется для уведомления вызывающего объекта о завершении длительной операции. Когда делегат используется таким образом, коду, использующему делегат, не требуются сведения о реализации используемого метода. Данные функциональные возможности похожи на возможности, предоставляемые интерфейсами инкапсуляции. Дополнительные сведения см. в разделе

 

 


 

11. Делегаты и события на платформе Microsoft .NET.

Событие представляет собой сообщение, посылаемое объектом, чтобы сигнализировать о совершении какого-либо действия. Это действие может быть вызвано в результате взаимодействия с пользователем, например при нажатии кнопки мыши, или может быть обусловлено логикой работы программы. Объект, вызывающий событие, называется отправителем события. Объект, который захватывает событие и реагирует на него, называется получателем события.

При обмене событиями классу отправителя событий не известен объект или метод, который будет получать (обрабатывать) сформированные отправителем события. Необходимо, чтобы между источником и получателем события имелся посредник (или механизм подобный указателю). .NET Framework определяет специальный тип (Delegate), обеспечивающий функциональные возможности указателя функции.

Делегат является классом, который может хранить ссылку на метод. В отличие от других классов класс делегата имеет подпись и может хранить ссылки только на методы, соответствующие этой подписи. Таким образом, делегат эквивалентен строго типизированному указателю функции или обратному вызову. Хотя делегаты имеют и другие направления использования, здесь будут рассматриваться только функциональные возможности делегатов по обработке событий. Объявление делегата является достаточным для определения класса делегата. Объявление предоставляет подпись делегата, а среда CLR обеспечивает реализацию. В следующем примере показан порядок объявления делегата событий.

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

delegate void EventHandler(object sender, EventArgs e);

 

Делегаты событий являются многоадресными. Это означает, что они могут хранить ссылки на несколько методов обработки событий. Дополнительные сведения см. в разделе Delegate. Делегаты позволяют осуществлять гибкий и детальный контроль при обработке событий. Делегат действует как диспетчер событий для класса, вызвавшего событие, обслуживая для события список зарегистрированных обработчиков событий.

---------------------------

Функциональные возможности события обеспечивают три взаимосвязанные элемента: класс, предоставляющий данные события, делегат события и класс, вызывающий событие. В среде .NET Framework используется соглашение по присвоению имен классам и методам, относящимся к событиям. Чтобы класс мог вызывать событие с именем EventName, необходимы следующие элементы:

· Класс, содержащий данные события, именуемый как EventNameEventArgs. Этот класс должен наследоваться от System.EventArgs.

· Делегат для события, именуемый как EventNameEventHandler.

· Класс, вызывающий событие. Этот класс должен предоставить объявление события (EventName) и метод, инициирующий событие (OnEventName).

Класс данных события и класс делегата события могут быть уже определены в библиотеке классов .NET Framework или в библиотеке классов независимых разработчиков. В данном случае не требуется определять эти классы. Например, если событие не использует пользовательские данные, то можно использовать System.EventArgs для данных события и System.EventHandler для делегата.

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

private EventNameHandler eh = null;

Компилятор также создает два открытых метода add_EventName и remove_EventName. Эти методы являются обработчиками событий, которые позволяют объединять или удалять делегаты из делегата события eh. Эти подробности скрыты от программиста.

После определения реализации события, необходимо определить, когда следует инициировать событие. Событие инициируется вызовом защищенного метода OnEventName в классе, определяющем событие, или в производном классе. Метод OnEventName вызывает событие посредством вызова делегатов, передавая все характерные для события данные. Методы делегата события могут выполнять действия для события или обрабатывать характерные для события данные.

При необходимости обработки событий, вызванных в другом классе, добавьте методы делегата к событию. Если вы не знакомы с моделью делегатов событий в .NET Framework, см. раздел События и делегаты.

using System;delegate void MyEventHandler();class MyEvent{ public event MyEventHandler SomeEvent;       public void OnSomeEvent() {   if (SomeEvent != null)       SomeEvent(); }}class CTest{     static void handler(){   Console.WriteLine("Some event!"); } static void Main(){         MyEvent evt = new MyEvent();   evt.SomeEvent += new MyEventHandler(handler);   evt.OnSomeEvent();           Console.ReadLine(); }

 

 


 

12. Классы и объекты на платформе .NET. Объявления. Хранение объектов в стеке и куче (heap).

Класс, по сути, является чертежом для пользовательского типа данных. Определив класс, его можно использовать, загрузив в память. Класс, загруженный в память, называется объектом или экземпляром. Экземпляр класса создается с помощью ключевого слова C# new.

Далее представлен пример определения класса с именем SampleClass и создание объекта с именем sampleClass1, который является экземпляром этого класса. Поскольку необходимо, чтобы функция Main была определена внутри класса, в следующем коде также определяется класс Program, однако он не используется для создания объекта.

Члены экземпляра и статические члены

Классы и файлы

Инкапсуляция

Наследование

Полиморфизм

 

Определение класса или структуры подобно чертежу, на котором указаны действия, выполняемые типом. В сущности, объект является блоком памяти, выделенной и настроенной в соответствии с чертежом. Программа может создать множество объектов одного класса. Объекты также называют экземплярами. Они могут храниться либо в именованной переменной, либо в массиве или коллекции. Клиентский код — это код, использующий эти переменные для вызова методов и доступа к открытым свойствам объекта. В объектно-ориентированном языке, таком как C#, стандартная программа состоит из нескольких динамически взаимодействующих объектов.

 

Поскольку классы являются ссылочными типами, в переменной объекта класса хранится ссылка на адрес объекта в управляемой куче. Если первому объекту назначен второй объект того же типа, обе переменные ссылаются на объект, расположенный по данному адресу. Эта особенность обсуждается более подробно далее в этом разделе.

Экземпляры классов создаются с помощью оператора new. В следующем примере Person является типом, а person1 и person 2 — являются экземплярами или объектами этого типа.

 

 

Person p1 = new Person("Wallace", 75); в кучеPerson p2; в стекеp2.Name = "Wallace";p2.Age = 75; if (p2.Equals(p1)) Console.WriteLine("p2 and p1 have the same values."); // Output: p2 and p1 have the same values.

 


 

13. Компонентное программирование, показать применение этого подхода на практике. Сборки и их устройство.

 


Компонентно-ориентированное программирование
(англ. component-oriented programming) возникло как своего рода дисциплина, то есть набор определенных ограничений, налагаемых на механизм ООП, когда стало ясно, что бесконтрольное использование ООП приводит к проблемам с надежностью больших программных комплексов.

Это так называемая проблема хрупких базовых типов (fragile base class problem); проблема может проявиться при попытке изменить реализацию типа-предка, когда может оказаться, что изменить реализацию типа-предка даже при неизменных интерфейсах его методов невозможно, не нарушив корректность функционирования типов-потомков.

Следует отметить, что структурное программирование ранее тоже возникло как некоторая дисциплина использования структур управления, исключающая бесконтрольные неупорядоченные переходы управления с помощью оператора GOTO.

 

Компонентное программирование в .NET

Пожалуй, наиболее существенным нововведением идеологии Microsoft .NET является компонентно-ориентированный подход к программированию.
Во-первых, следует отметить то обстоятельство, что компонентно-ориентированный подход к проектированию и реализации программных систем и комплексов является в некотором смысле развитием объектно-ориентированного и практически более пригоден для разработки крупных и распределенных систем (например, корпоративных приложений).
Прежде всего, сформулируем основополагающее для рассматриваемого подхода определение компонента. Под компонентом будем далее иметь в виду независимый модульпрограммного кода, предназначенный для повторного использования и развертывания. Как видно из определения, применение компонентного программирования призвано обеспечить более простую, быструю и прямолинейную процедуру первоначальной инсталляции прикладного программного обеспечения, а также увеличить процент повторного использования кода, т.е. усилить основные преимущества ООП.
Говоря о свойствах компонентов, следует прежде всего отметить, что это существенно более крупные единицы, чем объекты (в том смысле, что объект представляет собой конструкцию уровня языка программирования). Другими отличиями компонентов от традиционных объектов являются возможность содержать множественные классы и (в большинстве случаев) независимость от языка программирования.
Заметим, что, автор и пользователь компонента, вообще говоря, территориально распределены и используют разные языки. Вполне возможно, что они не только пишут программы, но и говорят на разных языках.
Получив представление о компонентах и их отличиях от традиционных объектов ООП, рассмотрим существующие подходы к моделированию вариаций компонентного подхода в современной практике проектирования и реализации программных комплексов и систем.
Прежде всего, поскольку основной вычислительной средой для исследования в данном курсе является Microsoft .NET, обсудим особенности модели для компонентно-ориентированной разработки программного обеспечения, предложенной корпорацией Microsoft. Эта модель называется компонентной объектной моделью (или Component Object Model, COM) и является изначальным стандартом, принятым для компонентной разработки приложений в корпорации Microsoft.
Компонентная модель COM определяет протокол для конкретизации (т.е. создания экземпляров) и использования компонент (по аналогии с классами и объектами) как внутри одного и того же процесса, так и между различными процессами или компьютерами, предназначенными для выполнения того или иного программного проекта, основанного на компонентной технологии. Модель COM является достаточно универсальной и используется в качестве фундамента для таких технологий проектирования и реализации программного обеспечения, как ActiveX, OLE и целого ряда других технологий. Приложения для COM-модели могут создаваться средствами таких языков и сред разработки как Visual Basic, C++, .NET и т.д.

Пример -

ASP.NET - технология для создания исполняемых на сервере сценариев. Технология позволяет обращаться к компонентам на сервере как к локальным компонентам среды выполнения. Страницы ASP.NET можно легко создавать при помощи визуального редактора, входящего в состав Visual Studio 2003. Сами страницы при этом являются объектами классов

В рамках компонентного подхода сборкой называется логическая единица, содержащая множество модулей, необходимых для осуществления инсталляции программного обеспечения. Сборка характеризуется уникальностью, которая обеспечивается идентификатором версии сборки и цифровой подписью автора. Сборка является самодостаточной единицей для установки программного обеспечения и не требует никаких дополнений. Возможно как индивидуальное, так и коллективное (сетевое) использование сборки на основе компонентной технологии. Сборка обеспечивает простой и удобный механизм инсталляции и экономит средства, необходимые дляразвертывания программного обеспечения, сводя к минимуму затраты времени и сил на установку.
Описание сборки содержится в так называемом манифесте, где хранятся метаданные о компонентах сборки, идентификация автора и версии, сведения о типах и зависимостях, а также режим и политика использования. Метаданные типов манифеста исчерпывающе описывают все типы, определенные в сборке, а именно, свойства, методы, аргументы, возвращаемые значения, атрибуты, базовые классы и т.д.
Заметим, что промежуточный язык IL всегда компилируется в естественный (native) код до выполнения программы.
Для более эффективного манипулирования системой типизации компонент создаваемого программного обеспечения в рамках модели COM, концепция .NET предусматривает механизм пространств имен (namespace).
Пространством имен будем называть механизм среды Microsoft .NET, предназначенный для идентификации типов объектов языков программирования и среды реализации.
Описания пространств имен по аналогии с описаниями типов данных размещаются в файлах. Перечислим основные свойства, которыми характеризуются пространства имен в среде Microsoft .NET. Прежде всего, пространства имен могут как объединять различные сборки, так и быть вложенными друг в друга. Кроме того, файлы с описаниями могут содержать множественные пространства имен. Важно отметить, что между пространствами имен и файлами не существует однозначного соответствия..

Рассмотрим особенности использования механизма сборок, важнейшей концепции компонентного программирования, применительно к языку C#. Сборка является минимальной единицей для развертывания приложений, т.е. представляет собой своеобразный атом компонентного программирования. Каждый тип сборки характеризуется уникальным идентификатором – номером версии сборки. Таким образом, каждый программный проект формируется в виде сборки, которая является самодостаточным компонентом для развертывания, тиражирования и повторного использования. Сборка идентифицируется цифровой подписью автора и уникальным номером версии. Между сборками и пространствами имен существует следующее соотношение. Сборка может содержать несколько пространств имен. В то же время, пространство имен может занимать несколько сборок. Сборка может иметь в своем составе как один, так и несколько файлов, которые объединяются в так называемом манифесте или описании сборки, который подобен оглавлению книги. Манифест содержит метаданные о компонентах сборки, идентификацию автора и версии, сведения о типах и зависимостях, а также описывает режим и политику использования сборки. Метаданные типов манифеста в полной мере описывают все типы, которые содержатся в сборке. В ходе обсуждения реализации механизма сборок в языке программирования C# следует отметить еще несколько важных характеристик. Прежде всего, сборка как элемент языка программирования C# является аналогом компонента в среде проектирования и реализации программного обеспечения Microsoft .NET. В результате компиляции программного кода на языке C# в среде вычислений .NET (например, в .NET Framework SDK) создается либо сборка, либо так называемый модуль. При этом сборка существует в форме исполняемого файла (с расширением EXE), а также файла динамически присоединяемой библиотеки (с расширением DLL). Естественно, в состав сборки входит манифест. Модуль представляет собой файл с расширением .NETMODULE и, в отличие от сборки, не содержит в своем составе манифеста. Заметим, что интеграция в программный проект других модулей и ресурсов (в частности, типов и метаданных) может быть осуществлена посредством системного программного обеспечения, известного под названием компоновщика сборок. Подводя итоги рассмотрения основных аспектов концепции компонентно-ориентированного подхода к программированию и особенностей реализации этой концепции применительно к языку программирования C#, кратко отметим достоинства подхода. Прежде всего, важным практическим следствием реализации концепции компонентного подхода для экономики программирования является снижение стоимости проектирования и реализации программного обеспечения. Еще одно очевидное достоинство компонентного программирования – возможность усовершенствования стратегии повторного использования кода. Код с более высокимуровнем абстракции не требует существенной модификации при адаптации к изменившимся условиям задачи или новым типам данных. Кроме того, к преимуществам концепции компонентного программирования следует отнести унификацию обработки объектов различной природы. В самом деле, абстрактные классы и методы позволяют единообразно оперировать гетерогенными данными, причем для адаптации к новым классам и типам данных не требуется реализации дополнительного программного кода. Важно также отметить, что идеология компонентного программирования основана на строгом математическом фундаменте (в частности, в виде формальной системы ламбда-исчисления), что обеспечивает интуитивную прозрачность исходного текста для математически мыслящего программиста, а также верифицируемость программного кода. Наконец, концепция компонентного программирования, по сути, универсальна и в равной степени применима для различных подходов к программированию, включая функциональный и объектно-ориентированный. Завершая вторую часть учебного курса, посвященного исследованию современных языков программирования (на примере языка программирования C#) и поддерживающих их сред вычислений (на примере инструментально-технологической платформы .NET), кратко резюмируем содержание рассмотренных вопросов и проблем. Прежде всего, нами был рассмотрен объектно-ориентированный подход к проектированию и реализации программного обеспечения в сопоставлении с другими подходами. Затем было дано представление о важнейших концепциях, которые составляют теоретическое и практическое основание объектно-ориентированного подхода к программированию. В частности, были рассмотрены концепции объекта, класса, метода, абстракции, инкапсуляции, наследования, полиморфизма, а также подходы к их формализации на основе исчисления ламбда-конверсий, комбинаторной логики, теории решеток и концептуализации. Далее, посредством перечисленных теорий были формализованы такие важнейшие аспекты объектно-ориентированных языков программирования, как синтаксис и семантика. Кроме того, было исследовано понятие типа, изучены основы теории типов и типизации в языках программирования, реализованных в среде вычислений .NET. Затем мы перешли к рассмотрению вопросов, связанных с событийно-ориентированным программированием. Наконец, было исследована трансформация ООП в приложении к среде .NET, которая привела к появлению компонентного подхода, основанного на объектной моделиCOM. Вполне естественно, что, исходя из обширного спектра и глубины рассматриваемой проблематики, ряд важнейших аспектов реализации современных языков программирования (в рамках изложенного курса) был лишь обозначен или изложен весьма конспективно. В связи с этим, представляет интерес систематическое изучение следующих вопросов:
  1. компонентная разработка интегрированных гетерогенных программных систем на профессиональном уровне (на примере языков программирования SML и C#);
  2. разработка событийно-управляемых приложений;
  3. математически строгий сравнительный анализ функционального и объектно-ориентированного подходов к программированию на основе изученных теоретических разделов computer science;
  4. формализация семантики событийно управляемого (и, возможно, компонентно-ориентированного) программирования.
Согласно общей концепции изложения курса, дальнейшие исследования имеет смысл вести синтетически по направлениям теоретического обоснования программирования на основе изученных формальных систем computer science и современной практики проектирования и реализации программного обеспечения на основе универсальной и прогрессивной программно-инструментальной платформы Microsoft .NET.

 

Сборка

{ заголовки и заглушки {}

  метаданные{}

модули

{

пространства имен

{

классы{переменные и методы}

классы{…}

}

пространства имен

{…

}

}

}

 


 

13(2). Компонентное программирование в .NET (1)

 


Поделиться:



Последнее изменение этой страницы: 2019-03-31; Просмотров: 201; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.067 с.)
Главная | Случайная страница | Обратная связь