Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
для ЯП.doc
Скачиваний:
28
Добавлен:
04.06.2015
Размер:
583.17 Кб
Скачать

Применение экспортированных функций dll

  1. Идентифицируйте функции в DLL.

Как минимум, должно быть указано имя функции и имя библиотеки DLL, содержащей функцию.

  1. Создайте класс для хранения функций DLL.

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

  1. Создайте прототипы в управляемом коде.

[Visual Basic] Используйте инструкцию Declare с ключевыми словами Function и Lib.В некоторых редких случаях можно использовать классDllImportAttribute с ключевыми словами Shared Function.Эти случаи объясняются далее в этом разделе.

[C#] Чтобы идентифицировать DLL и функцию, используйте класс DllImportAttribute.Пометьте метод модификаторами static и extern.

[C++] Чтобы идентифицировать DLL и функцию, используйте класс DllImportAttribute.Пометьте метод или функцию оболочки модификатором extern "C".

  1. Вызовите функцию DLL.

Пример использования функции MessageBox c++ Win32 API из user32.dll

public class Win32

{

    [DllImport("user32.dll", CharSet = CharSet.Auto)]

    public static extern IntPtr MessageBox(int hWnd, String text, String caption, uint type);

}

public class HelloWorld

{

    public static void Main()

    {

        Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);

    }

}

Варианты применения ????

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

Итерационные операторы

Итерационные операторы применяются в программах С# для выполнения каких-либо

повторяющихся действий, т. е. для организации циклов. Иногда эти операторы назы-

называются циклическими.

В этом разделе мы расскажем об использовании итерационных операторов for,

while, do и f oreach.

Оператор for

Оператор for предназначен для повторного выполнения оператора или группы опера-

операторов заданное количество раз. Вот как выглядит этот оператор в общем виде:

for ( [Инициализация]; [Условие];[Приращение])

<Оператор>

Оператор [Инициализация] выполняется один раз перед началом цикла.

Перед каждой итерацией (т.е. перед каждым выполнением тела цикла «Эпера-

тор>) проверяется [Условие]. И наконец, после каждой итерации выполняется опе-

оператор [Прирашение].

Как правило, в цикле имеется переменная, играющая роль так называемой пере-

переменной цикла. При каждой итерации переменная цикла изменяет свое значение в за-

заданных пределах.

Начальное значение переменной цикла задается в программе до оператора for или

в операторе [Инициализация]. Предельное значение переменной цикла определяется

оператором приращения, а проверка ее текущего значения — в блоке [ Условие ].

Поясним сказанное на простом примере.

int i ;

forfi = 0; i < 10; i++)

{

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

}

Здесь переменная i используется в качестве переменной цикла. Перед началом

цикла ей присваивается нулевое значение. Перед каждой итерацией содержимое пере-

переменной i сравнивается с числом 10. Если i меньше 10, тело цикла выполняется один

раз. В тело цикла мы поместили вызов метода Write, отображающий текущее значе-

значение переменной цикла на консоли.

После выполнения тела цикла значение i увеличивается на единицу в блоке при-

приращения. Далее переменная цикла вновь сравнивается с числом 10. Когда значение i

превысит 10, цикл завершится.

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

а модифицируется после его выполнения.

Вот что выведет на консоль приведенный выше фрагмент программы:

0123456789

Прерывание цикла

С помощью оператора break можно в любой момент прервать выполнение цикла.

Например, в следующем фрагменте программы мы прерываем работу цикла, когда

значение переменной i становится больше пяти:

for(i = 0; i < 10;

if(i > 5)

break;

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

Возобновление цикла

В отличие от оператора break, прерывающего цикл, оператор continue позволяет

возобновить выполнение цикла с самого начала.

Вот как он используется:

for(i = 0;;

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

if(i < 9)

continue;

else

break;

}

В отличие от оператора 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, а нам останется только выводить при

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

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

делегат — это тип, который определяет подпись метода и его можно связать с любым методом с совместимой подписью. Метод можно запустить (или вызвать) с помощью делегата. Делегаты используются для передачи методов в качестве аргументов к другим методам. Обработчики событий — это ничто иное, как методы, вызываемые с помощью делегатов. Создание пользовательского метода и класса, например элемента управления 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 нельзя создавать производные пользовательские классы. Поскольку созданный экземпляр делегата является объектом, его можно передавать как параметр или назначать свойству. Это позволяет методу принимать делегат в качестве параметра и вызывать делегат впоследствии. Эта процедура называется асинхронным обратным вызовом и обычно используется для уведомления вызывающего объекта о завершении длительной операции. Когда делегат используется таким образом, коду, использующему делегат, не требуются сведения о реализации используемого метода. Данные функциональные возможности похожи на возможности, предоставляемые интерфейсами инкапсуляции. Дополнительные сведения см. в разделе

  1. Делегаты и события на платформе 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();

}

  1. Классы и объекты на платформе .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.

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

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

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

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

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

Пожалуй, наиболее существенным нововведением идеологии Microsoft .NET является компонентно-ориентированный подход к программированию. Во-первых, следует отметить то обстоятельство, что компонентно-ориентированный подход к проектированию и реализации программных систем и комплексов является в некотором смысле развитием объектно-ориентированного и практически более пригоден для разработки крупных и распределенных систем (например, корпоративных приложений). Прежде всего, сформулируем основополагающее для рассматриваемого подхода определение компонента. Под компонентом будем далее иметь в виду независимый модульпрограммного кода, предназначенный для повторного использования и развертывания. Как видно из определения, применение компонентного программирования призвано обеспечить более простую, быструю и прямолинейную процедуру первоначальной инсталляции прикладного программного обеспечения, а также увеличить процент повторного использования кода, т.е. усилить основные преимущества ООП. Говоря о свойствах компонентов, следует прежде всего отметить, что это существенно более крупные единицы, чем объекты (в том смысле, что объект представляет собой конструкцию уровня языка программирования). Другими отличиями компонентов от традиционных объектов являются возможность содержать множественные классы и (в большинстве случаев) независимость от языка программирования. Заметим, что, автор и пользователь компонента, вообще говоря, территориально распределены и используют разные языки. Вполне возможно, что они не только пишут программы, но и говорят на разных языках. Получив представление о компонентах и их отличиях от традиционных объектов ООП, рассмотрим существующие подходы к моделированию вариаций компонентного подхода в современной практике проектирования и реализации программных комплексов и систем. Прежде всего, поскольку основной вычислительной средой для исследования в данном курсе является Microsoft .NET, обсудим особенности модели для компонентно-ориентированной разработки программного обеспечения, предложенной корпорацией Microsoft. Эта модель называется компонентной объектной моделью (или Component Object ModelCOM) и является изначальным стандартом, принятым для компонентной разработки приложений в корпорации 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)

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

• Компоненты – это:

– независимые повторно используемые и

тиражируемые модули;

– в целом более крупные, чем объект

(объекты – конструкции уровня ЯП);

– могут содержать множественные классы;

– независимы от языка реализации.

• В общем случае, разработчик и пользователь

компонента территориально разделены и пользуются

разными языками в единой среде.

Современные языки программирования и .NET: II семестр

Лекция 2: Платформа .NET и ее применение для ООП

© Учебный Центр безопасности информационных технологий Microsoft

Московского инженерно-физического института (государственного университета), 2003

Комментарий к слайду

Одним из принципиальных технологических преимуществ проектирования и реализации

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

компонентный подход к программированию.

В своей основе указанный подход совпадает с традиционным объектно-ориентированным,

однако имеет ряд важных особенностей. Поскольку конечной целью данной части

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

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

подход.

Центральной концепцией подхода (и это очевидно уже из названия) является понятие

компонента.

Под компонентом в дальнейшем будем понимать независимый модуль программного

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

В отличие от «традиционных» объектов ООП компоненты обладают следующими

характеристическими свойствами:

• в целом компонент обладает более высоким уровнем абстракции по сравнению с

объектом (если под последним понимается конструкция уровня языка

программирования);

• компоненты могут содержать в своем составе множественные классы;

• компоненты с точки зрения пользователя являются инвариантами по отношению к

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

Таким образом, оказывается, что в общем случае разработчик и пользователь компонента

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

программирования в рамках единой среды разработки приложений Microsoft .NET.

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

• Компонентная объектная модель (COM):

– основной стандарт Microsoft для компонент;

– содержит протокол для инициализации и

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

между процессами или между компьютерами;

– основа для ActiveX, OLE и многих других технологий;

– поддерживается в Visual Basic, C++, .NET и др.

• Модель Java Beans:

– основной стандарт Sun Microsystems для компонент;

– зависима от языка реализации.

Современные языки программирования и .NET: II семестр

Лекция 2: Платформа .NET и ее применение для ООП

© Учебный Центр безопасности информационных технологий Microsoft

Московского инженерно-физического института (государственного университета), 2003

Комментарий к слайду

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

и рядом других компаний – разработчиков программного обеспечения (в частности,

технология JavaBeans производства Sun Microsystems), а также международных

ассоциаций, объединяющих усилия исследователей и практиков в области объектного

программирования (например, стандарт брокеров объектных запросов CORBA

организации Object Management Group, или OMG).

В основе таких попыток лежали варианты объектных моделей. Один из подобных

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

двухуровневой концептуализации, нам предстоит рассмотреть в ходе данного курса.

Сейчас же лишь кратко охарактеризуем основные отличительные особенности наиболее

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

объектных моделей.

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

именуется в литературе аббревиатурой COM (что происходит от слов Component Object

Model).

Компонентная объектная модель COM является основным стандартом Microsoft для

компонентного проектирования и реализации программного обеспечения. На сегодня это

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

практически обеспечивает возможность инициализации и использования компонентов

как внутри одного процесса, так и между процессами или между компьютерами

независимо от языка реализации. COM-модель поддерживается в идеологии .NET для

целого ряда языков программирования (C#, SML, Visual Basic, C++ и др.), является

основой для ActiveX, OLE, а также для многих других технологий Microsoft.

В отличие от СОМ, модель Java Beans, базовый стандарт Sun Microsystems для компонент,

оказывается зависимой от языка реализации.__

  1. Концепция применения программных платформ. Преимущества применения программных платформ при разработке приложений (на примере Microsoft .NET)

Платформа Microsoft .NET Framework

Платформа Microsoft .NET Framework, предназначенная для работы приложений Mi-

Microsoft .NET, дает большие преимущества разработчикам программ. В частности, она

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

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

Среди других преимуществ Microsoft .NET Framework заслуживает упоминания

наличие обширной библиотеки классов, существенно облегчающей решение задач,

наиболее часто возникающих при создании автономных программ и Web-приложений.

Эта библиотека, насчитывающая десятки тысяч (!) классов, готовых к употреблению,

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

Платформа Microsoft .NET Framework обеспечивает возможность использова-

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

компонентам из разработанного ранее программного кода. В результате после от-

относительно небольших переделок старые программы смогут приобрести новую

функциональность.

Приложения Microsoft .NET работают в среде Microsoft .NET Framework в рамках

системы исполнения программ Common Language Runtime (CLR). Примененная в Mi-

Microsoft .NET Framework концепция управляемого кода обеспечит надежное и безопас-

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

ошибок в процессе программирования. Этому же способствует система обработки ис-

исключений и система автоматического освобождения неиспользуемой оперативной па-

памяти, называемой системой сборки мусора (garbage collection).

Встроенные в язык С# и рассчитанные на среду Microsoft .NET Framework

средства документирования, такие, как атрибуты и операторы комментариев спе-

специального вида, позволят существенно упростить создание конструкторской доку-

документации на программный код. Это особенно ценно при разработке больших про-

проектов, когда из-за сложности и объемности задачи сопровождение разработки пре-

превращается в непосильную задачу и становится настоящим кошмаром для менед-

менеджера проекта.

В сочетании с мощным средством ускоренной разработки приложений Microsoft

Visual Studio .NET набор языков платформы Microsoft .NET послужит отличным под-

подспорьем при создании программ самого разного типа, как автономных, так и рассчи-

рассчитанных на использование в Интернете.

Концепция виртуальной машины возникла очень давно, еще на заре компьютерной

техники. Эта концепция была реализована в ОС IBM VM, созданной для «больших»

вычислительных машин (мейнфреймов) серии IBM 360/370.

ОС IBM VM разделяла физические ресурсы одного дорогостоящего компьютера

между несколькими ОС. Каждая ОС получала в пользование виртуальные ресурсы

компьютера — виртуальный диск, виртуальный процессор, виртуальную оперативную

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

на своем виртуальном компьютере (виртуальной машине).

Некоторые ресурсы (например, дисковое пространство и участки оперативной па-

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

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

на какое-то время сначала одной виртуальной машине, затем другой и т. д. При этом

создавалось впечатление, что все ОС работают одновременно.

Современные системы виртуальных машин, такие, как, например, VMWare, позво-

позволяют запускать на одном компьютере сразу несколько ОС — Microsoft Windows раз-

различных версий, MS-DOS, Linux и др. Лишь бы хватило мощности процессора, объема

дисковой и оперативной памяти.

Для нас сейчас принципиально важным является то, что программы, работающие

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

виртуальной машины. Если такая программа выполнит недопустимую операцию

и «повесит» ОС своей виртуальной машины, это никак не отразится на работоспособ-

работоспособности других виртуальных машин.

Так вот, виртуальная машина CLR, обеспечивающая работу программ платформы

Microsoft .NET Framework, закрывает доступ этим программам к ресурсам других про-

процессов, работающих на том же компьютере. В результате программа никоим образом

не сможет нарушить работоспособность остальных программ или ОС.

Компилятор JIT

Еще одним преимуществом технологии, предоставляемой в рамках платформы Micro-

Microsoft .NET Framework, перед традиционными технологиями программного обеспечения

является наличие так называемых сборок. Сборка представляет собой один или не-

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

но и для ее самодокументирования.

Упрощение отладки программ С#

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

времени и сил, чем на ее разработку и написание. Объем отладочного кода, создаваемого

специально для тестирования модулей программы, может многократно превышать

объем кода самих отлаживаемых модулей.

Исполнимый код, получающийся в результате трансляции исходного текста про-

программы, написанной на таких языках программирования, как C++ и Pascal, имеет

практически полный доступ к ресурсам своего процесса. Такие ошибки, как чтение

неинициализированных переменных, неправильное преобразование типов указателей

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

полученных блоков памяти, ошибки при выполнении числовых операций, могут при-

привести к аварийному завершению программы или к другим плачевным результатам.

Многие ошибки обычно остаются незамеченными на этапе компиляции и сказыва-

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

неподходящий момент.

Компилятор языка С# исключает возникновение перечисленных выше и многих

других ошибок еще на этапе компиляции, что существенно облегчает и ускоряет про-

процесс отладки сложных программ. Необходимые для этого средства встроены непо-

непосредственно в язык С#.

Среди других средств, встроенных в язык С# и упрощающих отладку программ,

следует упомянуть объектно-ориентированную обработку исключений и систему

сборки мусора.

1. Легкость развертывания приложений в глобальной среде

Интернет

2. Экономичная разработка программного обеспечения

3. «Бесшовная», гибкая интеграция программных продуктов

и аппаратных ресурсов

4. Предоставление программного обеспечения как сервиса

5. Новый уровень безопасности и удобства использования

Компонентный подход как развитие объектно-

ориентированной модели

2. Универсальная система типизации: «всякая сущность

есть объект»; унификация данных и метаданных

3. Строго иерархическая организация кода, пространств

имен и классов

4. Универсальный интерфейс .NET Framework (включая

поддержку различных подходов к программированию)

5. Высокая вариативность экземпляров реализации (в

частности, на основе веб-сервисов)

Многоязыковая поддержка (десятки языков

программирования)

  1. Массивы в языке С#. Объявление и применение массивов в языке С#, обращение к элементам массива.

Массив — это структура данных, содержащая несколько переменных одного типа. Массивы объявляются со следующим типом.

type[] arrayName;

// Declare a single-dimensional array

int[] array1 = new int[5];

// Declare and set array element values

int[] array2 = new int[] { 1, 3, 5, 7, 9 };

// Alternative syntax

int[] array3 = { 1, 2, 3, 4, 5, 6 };

// Declare a two dimensional array

int[,] multiDimensionalArray1 = new int[2, 3];

// Declare and set array element values

int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } };

// Declare a jagged array

int[][] jaggedArray = new int[6][];

// Set the values of the first array in the jagged array structure

jaggedArray[0] = new int[4] { 1, 2, 3, 4 };

int[][] jaggedArray = new int[2][];

jaggedArray[0] = new int[4];

jaggedArray[1] = new int[3];

В платформе .NET Framework массивы реализуются как экземпляры класса Array. Этот класс обеспечивает несколько ценных методов, например Sort иReverse.

Типы массива являются ссылочными типами, производными от абстрактного базового типа Array. Поскольку этот тип реализует IEnumerable иIEnumerable<T>, в C# во всех массивах можно использовать итерацию foreach.

Невыровненный массив является массивом массивов, и поэтому его элементы являются ссылочными типами и инициализируются значением null.

int[][] jaggedArray3 =

{

new int[] {1,3,5,7,9},

new int[] {0,2,4,6},

new int[] {11,22}

};

  1. Обработка исключений на платформе Microsoft .NET. Практическое применение.

Для работы с исключениями код должен быть организован особым образом. Часть кода, в которой может быть выработано исключение, заключается в блок try, а код, обрабатывающий исключение - в блок catch. Исключения могут вырабатываться самой CLR (например при попытке деления на 0) либо пользовательским методом, для чего служит ключевое слово throw после которого указывается объект-исключение, передаваемый в блок catch. Класс этого объекта должен быть производными от класса Exception. В отличие от С++ имеется блок finally. Код, заключенный в блок finally будет выполнен как при обычном завершении работы блока try, так и при вызове исключения в этом блоке. Если перед завершением функции, исполнение которой может быть прервано исключением, обязательно должны быть выполнены некоторые действия (например, закрытие ранее открытого файла), следует заключить соответствующий код в блок finally.

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

  1. Объектно-ориентированный подход к программированию. Классы и объекты. Определения; Определения классов и объектов. Проблемы, решаемые этим подходом.

Объектно-ориентированное программирование или ООП (object-orientedprogramming) -- методология программирования, основанная на представлении программы в виде совокупности объектов, каждый изкоторый является реализацией определенного типа, использующая механизм пересылки сообщений и классы, организованные в иерархию наследования.

Центральный элемент ООП –абстракция. Данные с помощью абстракции преобразуются в объекты, а последовательность обработки этих данных превращается в набор сообщений, передаваемых между этими объектами. Каждый из объектов имеет свое собственное уникальное поведение. С объектами можно обращаться как с конкретными сущностями, которые реагируют на сообщения, приказывающие им выполнить какие-то действия.

ООП характеризуется следующими принципами (по Алану Кею):

- все является объектом;

- вычисления осуществляются путем взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие; объекты взаимодействуют, посылая и получая сообщения; сообщение -- это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия;

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

- каждый объект является представителем класса, который выражает общие свойства объектов данного типа;

- в классе задается функциональность (поведение объекта); тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия;

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

Абстрагирование (abstraction) -- метод решения задачи, при котором объекты разного рода объединяются общим понятием (концепцией), а затем сгруппированные сущности рассматриваются как элементы единой категории.

Абстрагирование позволяет отделить логический смысл фрагмента программы от проблемы его реализации, разделив внешнее описание (интерфейс) объекта и его внутреннюю организацию (реализацию).

Инкапсуляция (encapsulation) -- техника, при которой несущественная с точки зрения интерфейса объекта информация прячется внутри него.

Наследование (inheritance) -- свойство объектов, посредством которого экземпляры класса получают доступ к данным и методам классов-предков без их повторного определения.

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

Полиморфизм (polymorphism) -- свойство, позволяющее использовать один и тот же интерфейс для различных действий; полиморфной переменной, например, может соответствовать несколько различных методов.

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

Класс (class) -- множество объектов, связанных общностью структуры и поведения; абстрактное описание данных и поведения (методов) для совокупности похожих объектов, представители которой называются экземплярами класса.

Объект (object) -- конкретная реализация класса, обладающая характеристиками состояния, поведения и индивидуальности, синоним экземпляра.

Плюсы ООП:

От любого метода программирования мы ждем, что он поможет нам в решении наших проблем. Но одной из самых значительных проблем в программировании является сложность. Чем больше и сложнее программа, тем важнее становится разбить ее на небольшие, четко очерченные части. Чтобы побороть сложность, мы должны абстрагироваться от мелких деталей. В этом смысле классы представляют собой весьма удобный инструмент.

ООП дает возможность создавать расширяемые системы (extensiblesystems). Это одно из самых значительных достоинств ООП и именно оно отличает данный подход от традиционных методов программирования. Расширяемость (extensibility) означает, что существующую систему можно заставить работать с новыми компонентами, причем без внесения в нее каких-либо изменений. Компоненты могут быть добавлены на этапе выполнения.

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

  1. Операторы ветвления на языке C#.

Операторы ветвления изменяют поток выполнения программы во время выполнения согласно определенным условиям.