Ключевым элементом для понимания природы взаимодействия объектов программы в
Ранее нами было рассмотрено понятие типа как совокупности объектов. Заметим, что произвольное семейство (действительных в нашем частном случае) объектов может быть параметризовано (или, иначе, концептуализировано) не только типами, но и
В соответствии со схемой ||.|| переводит индивид h- языка (в частности, языка программирования) в h. Затем h из семейства H переводится i из семейства Asg в h(i) из семейства Ui. Аналогично, следующий шаг преобразований, управляемый j из семейства Asg, переводит h(i) в h(i)(j) (см. рис. 23.1).
(рис 23.1) Схема двухуровневой концептуализации объектов данных.На первый взгляд, определение понятия
Как только происходит изменение
Любой современный интерфейс пользователя (или, в математической терминологии, onClick, onMouseMove, onMouseOver и т.д.).
В соответствии со схемой
После изложения понятийного аппарата концепции
В целях реализации механизма
Заметим, что
Преимущество
В качестве иллюстрации приведем описание типа- и
delegate void Notifier (string sender); // обычное описание метода с // ключевым словом delegate Notifier greetings; // описание переменной-делегата
Как видно из приведенного фрагмента программы, формально описание типов- и
Фундаментальное отличие
void SayHello(string sender) {
Console.WriteLine(
"Hello from " + sender);
}
greetings = new Notifier(SayHello);
Как видно из приведенного примера, на основе ранее описанного типа-делегата Notifier в SayHello осуществляется присваивание значения переменной . Фактически данный пример изображает первый
Проиллюстрируем далее порядок вызова
greetings("John");
// активирует SayHello("John") =>
"Hello from John"
Как мы видим, означивание активизирует SayHello в "John" с генерацией "Hello from John". Фактически данный пример изображает второй
Для более наглядной иллюстрации работы
void SayGoodBye(string sender) {
Console.WriteLine(
"Good bye from " + sender);
}
greetings = new Notifier(SayGoodBye);
greetings("John");
//SayGoodBye("John") =>
"Good bye from John"
Как видно из приведенного примера, типа Notifier может принимать в качестве значения любой из методов SayHello и SayGoodBye.
В данном случае, в отличие от предыдущего примера, значением, вычисляемым в ходе выполнения метода SayGoodBye, , является "Good bye from John", полученная на основе означивания SayGoodBye("John").
Таким образом, становится ясным, каким образом посредством активизации (в зависимости от значения
Для более подробного рассмотрения механизмов расширенного управления программой на языке C# посредством
Прежде всего, следует отметить то обстоятельство, что null, что соответствует отсутствию назначенного им метода. Здесь проявляется аналогия с
Кроме того, пустые
Еще одной особенностью
Таким образом,
Обсудив основные возможности описания и использования
Прежде всего, рассмотрим порядок описания языкового объекта-делегата. Проиллюстрируем обобщение создания
<описание_переменной-делегата>::=
new <тип_делегата>
(<объект>.<метод>);
При этом
new Notifier(myObj.SayHello);
В данном фрагменте программного кода на языке C# приведен пример описания Notifier в SayHello определенного пользователем объекта myObj. Заметим, что присутствующий в описании объект myObj cможет быть определен явно посредством описателя this, а может быть и опущен, как, например, в следующем фрагменте программы на языке C#:
new Notifier(SayHello);
Обсудив основные возможности описания и использования
При этом обобщенный формат описания
<описание_переменной-делегата>::=
new <тип_делегата>
(<класс>.<метод>)
Таким образом, описание
new Notifier(MyClass.StaticSayHello);
Существует еще ряд особенностей, характеризующих статический случай использования
Прежде всего, следует отметить, что метод в составе
Кроме того, описание метода должно соответствовать описанию типа ref ), по значению ( value ), а также возвращаемые ( out )) должны совпадать.
Еще одним важным свойством
Практика программирования на языке C# показывает, что
Notifier greetings;
greetings = new Notifier(SayHello);
greetings += new Notifier(SayGoodbye);
greetings("John");
// "Hello from John"
// "Good bye from John"
greetings -= new Notifier(SayHello);
greetings("John");
// "Good bye from John"
Как видно из приведенного примера, фрагмент программы на языке C# содержит описание уже известной нам типа-делегата Notifier. в качестве значения последовательно инкрементно присваиваются конкретизации-методы SayHello и SayGoodbye. При этом отладочный вывод значения переменной с "John" демонстрирует семейство значений "Hello from John" и "Good bye from John". После декрементного присваивания конкретизации-метода SayHello отладочный вывод значения переменной демонстрирует значение "Good bye from John".
Заметим, что если множественный
Обсудив наиболее существенные для данного курса аспекты типов- и
Проиллюстрируем подход к
class Model {
public event Notifier notifyViews;
public void Change() {
...
notifyViews("Model");
}
}
class View1 {
public View1(Model m) {
m.notifyViews +=
new Notifier(this.Update1);
}
void Update1(string sender){
Console.WriteLine(
sender + "was changed");
}
}
class View2 {
public View2(Model m){
m.notifyViews +=
new Notifier(this.Update2);
}
void Update2(string sender){
Console.WriteLine(
sender + " was changed");
}
}
class Test {
static void Main() {
Model m = new Model();
new View1(m);
new View2(m);
m.Change();
}
}
Как видно из приведенного примера, фрагмент программы на языке C# содержит описание класса Model с полем-событием notifyViews (описатель event ) и методом Change, оповещающим через View1 с одноименными методом для просмотра Update1, содержащего вывод на стандартное устройство отладочной информации о смене приложения-"отправителя" сообщения.
Пример завершается описанием класса View2, аналогичного классу View1, а также класса Test, который инициализирует классы View1 и View2 и запускает метод Change, инициирующий смену
Заметим, что
Процесс языка C#, предназначенного для обнаружения и обработки ошибок, на следующем примере:
FileStream s = null;
try {
s = new FileStream(
curName, FileMode.Open);
...
catch (FileNotFoundException e){
Console.WriteLine(
"file {0} not found",
e.FileName);
}
catch (IOException){
Console.WriteLine(
"some IO exception
occurred");
}
catch {
Console.WriteLine(
"some unknown error
occurred");
}
finally if (s != null)
s.Close();
}
Как видно из примера, оператор анализирует выход функции чтения из потокового файла. Для обработки вариантов при разборе возможных ошибочных ситуаций используется оператор , в данном примере генерирующий диагностические сообщения. В случае ложности всех -альтернатив выполняется (происходит штатное закрытие файла).
По результатам анализа приведенного фрагмента программы на языке C# рассмотрим основные характеристики обработки
Прежде всего, необходимо отметить то обстоятельство, что в составе оператора проверяются последовательно сверху вниз.
Таким образом, при полном разборе случаев разработчиком программного обеспечения одно из всегда удовлетворяется (естественно, в том случае, если список условий не пуст).
Кроме того, синтаксис языка программирования C# разрешает опустить имя параметра в .
Далее, заметим, что тип должен быть выводим из базового класса System.Exception.
Наконец, важным свойством оператора является тот факт, что при отсутствии явного указания параметра подразумевается System.Exception
Для иллюстрации особенностей механизма обработки System.Exception
Как видно из приведенной таблицы, класс System.Exception представляет собой описание многочисленных объектов и методов, которые контролируют стандартный ход обработки
| Имя свойства или метода | Функции свойства или метода |
|---|---|
| Свойства: | |
e.Message |
сообщение об ошибке в виде строки |
e.StackTrace |
просмотр |
e.Source |
приложение или объект, которые вызвали исключительную ситуацию |
e.TargetSite |
метод объекта, который вызвал исключительную ситуацию |
| ... | |
| Методы: | |
e.ToString() |
возвращает имя исключительной ситуации |
| ... |
При исследовании механизмов обработки
Исходя из вида изученного оператора языка программирования C#, а также из стандартных свойств и методов обработки System.Exception
К неявным источникам null ) указателю и т.д.
Однако для реализации событийно управляемых программ в языке программирования C# существует механизм явной генерации throw (приводим соответствующий фрагмент программы):
throw new FunnyException(10);
class FunnyException : ApplicationException
{
public int errorCode;
public FunnyException(int x){
errorCode = x;
}
}
Как видно из приведенного фрагмента программы, оператор throw реализует явный вызов FunnyException с генерацией кода ошибки.
Заметим, что в силу высокой сложности и гетерогенной природы
Для удобства систематизации, хранения, поиска и анализа
Приведем для сведения небольшой фрагмент сложной структуры иерархии стандартных
Exception
SystemException
ArithmeticException
DivideByZeroException
OverflowException
...
NullReferenceException
IndexOutOfRangeException
InvalidCastException
...
Заметим, что существует еще более общий уровень иерархии SystemException, а именно, уровень Exception.
В данной иерархии
Другим подклассом
Продолжим анализ иерархии
ApplicationException
...// специализированные исключения
...
IOException
FileNotFoundException
DirectoryNotFoundException
...
WebException
...
Отдельный подкласс
Еще одним важным подклассом
Наконец, еще одним подклассом
Рассмотрим особенности реализации механизма реакции на
Поиск
Осуществляется просмотр цепочки вызовов методов в обратном направлении до тех пор, пока не будет найден метод с соответствующим . Если такой метод обнаружить не удается, программа завершается аварийно и выдается
Подчеркнем, что алгоритм поиска
Заметим, что в языке C# не существует различия между помеченными
Несмотря на то, что такой подход в первом приближении представляется удобным, он заведомо приводит к созданию менее устойчивого и безопасного прикладного (и тем более системного) программного кода.
Подводя итоги рассмотрения основных аспектов теории и практики событийно управляемого программирования на языке C#, можно сделать следующие выводы.
Во-первых, как и в объектно-ориентированном программировании,
Во-вторых, событийно ориентированное программирование обеспечивает потенциальную легкость настройки интерфейса пользователя (и его адаптации в процессе работы программы в соответствии с требованиями пользователя).
Кроме того, процедуры
Затем, важным преимуществом программирования, ориентированного на
Далее, необходимо отметить такой позитивный аспект событийного программирования как гибкость реинжиниринга (т.е. разработки в обратном направлении) программного обеспечения. По сути, речь идет о
Именно концептуализация составляет то строгое математическое основание, которое позволяет не только моделировать
Для более подробного самостоятельного ознакомления с тематикой лекции рекомендуется следующий список источников: [ 24, 28, 36, 66-69, 79-81].
Ключевым элементом для понимания природы взаимодействия объектов программы в
Ранее нами было рассмотрено понятие типа как совокупности объектов. Заметим, что произвольное семейство (действительных в нашем частном случае) объектов может быть параметризовано (или, иначе, концептуализировано) не только типами, но и
В соответствии со схемой ||.|| переводит индивид h- языка (в частности, языка программирования) в h. Затем h из семейства H переводится i из семейства Asg в h(i) из семейства Ui. Аналогично, следующий шаг преобразований, управляемый j из семейства Asg, переводит h(i) в h(i)(j) (см. рис. 23.1).
(рис 23.1) Схема двухуровневой концептуализации объектов данных.На первый взгляд, определение понятия
Как только происходит изменение
Любой современный интерфейс пользователя (или, в математической терминологии, onClick, onMouseMove, onMouseOver и т.д.).
В соответствии со схемой
После изложения понятийного аппарата концепции
В целях реализации механизма
Заметим, что
Преимущество
В качестве иллюстрации приведем описание типа- и
delegate void Notifier (string sender); // обычное описание метода с // ключевым словом delegate Notifier greetings; // описание переменной-делегата
Как видно из приведенного фрагмента программы, формально описание типов- и
Фундаментальное отличие
void SayHello(string sender) {
Console.WriteLine(
"Hello from " + sender);
}
greetings = new Notifier(SayHello);
Как видно из приведенного примера, на основе ранее описанного типа-делегата Notifier в SayHello осуществляется присваивание значения переменной . Фактически данный пример изображает первый
Проиллюстрируем далее порядок вызова
greetings("John");
// активирует SayHello("John") =>
"Hello from John"
Как мы видим, означивание активизирует SayHello в "John" с генерацией "Hello from John". Фактически данный пример изображает второй
Для более наглядной иллюстрации работы
void SayGoodBye(string sender) {
Console.WriteLine(
"Good bye from " + sender);
}
greetings = new Notifier(SayGoodBye);
greetings("John");
//SayGoodBye("John") =>
"Good bye from John"
Как видно из приведенного примера, типа Notifier может принимать в качестве значения любой из методов SayHello и SayGoodBye.
В данном случае, в отличие от предыдущего примера, значением, вычисляемым в ходе выполнения метода SayGoodBye, , является "Good bye from John", полученная на основе означивания SayGoodBye("John").
Таким образом, становится ясным, каким образом посредством активизации (в зависимости от значения
Для более подробного рассмотрения механизмов расширенного управления программой на языке C# посредством
Прежде всего, следует отметить то обстоятельство, что null, что соответствует отсутствию назначенного им метода. Здесь проявляется аналогия с
Кроме того, пустые
Еще одной особенностью
Таким образом,
Обсудив основные возможности описания и использования
Прежде всего, рассмотрим порядок описания языкового объекта-делегата. Проиллюстрируем обобщение создания
<описание_переменной-делегата>::=
new <тип_делегата>
(<объект>.<метод>);
При этом
new Notifier(myObj.SayHello);
В данном фрагменте программного кода на языке C# приведен пример описания Notifier в SayHello определенного пользователем объекта myObj. Заметим, что присутствующий в описании объект myObj cможет быть определен явно посредством описателя this, а может быть и опущен, как, например, в следующем фрагменте программы на языке C#:
new Notifier(SayHello);
Обсудив основные возможности описания и использования
При этом обобщенный формат описания
<описание_переменной-делегата>::=
new <тип_делегата>
(<класс>.<метод>)
Таким образом, описание
new Notifier(MyClass.StaticSayHello);
Существует еще ряд особенностей, характеризующих статический случай использования
Прежде всего, следует отметить, что метод в составе
Кроме того, описание метода должно соответствовать описанию типа ref ), по значению ( value ), а также возвращаемые ( out )) должны совпадать.
Еще одним важным свойством
Практика программирования на языке C# показывает, что
Notifier greetings;
greetings = new Notifier(SayHello);
greetings += new Notifier(SayGoodbye);
greetings("John");
// "Hello from John"
// "Good bye from John"
greetings -= new Notifier(SayHello);
greetings("John");
// "Good bye from John"
Как видно из приведенного примера, фрагмент программы на языке C# содержит описание уже известной нам типа-делегата Notifier. в качестве значения последовательно инкрементно присваиваются конкретизации-методы SayHello и SayGoodbye. При этом отладочный вывод значения переменной с "John" демонстрирует семейство значений "Hello from John" и "Good bye from John". После декрементного присваивания конкретизации-метода SayHello отладочный вывод значения переменной демонстрирует значение "Good bye from John".
Заметим, что если множественный
Обсудив наиболее существенные для данного курса аспекты типов- и
Проиллюстрируем подход к
class Model {
public event Notifier notifyViews;
public void Change() {
...
notifyViews("Model");
}
}
class View1 {
public View1(Model m) {
m.notifyViews +=
new Notifier(this.Update1);
}
void Update1(string sender){
Console.WriteLine(
sender + "was changed");
}
}
class View2 {
public View2(Model m){
m.notifyViews +=
new Notifier(this.Update2);
}
void Update2(string sender){
Console.WriteLine(
sender + " was changed");
}
}
class Test {
static void Main() {
Model m = new Model();
new View1(m);
new View2(m);
m.Change();
}
}
Как видно из приведенного примера, фрагмент программы на языке C# содержит описание класса Model с полем-событием notifyViews (описатель event ) и методом Change, оповещающим через View1 с одноименными методом для просмотра Update1, содержащего вывод на стандартное устройство отладочной информации о смене приложения-"отправителя" сообщения.
Пример завершается описанием класса View2, аналогичного классу View1, а также класса Test, который инициализирует классы View1 и View2 и запускает метод Change, инициирующий смену
Заметим, что
Процесс языка C#, предназначенного для обнаружения и обработки ошибок, на следующем примере:
FileStream s = null;
try {
s = new FileStream(
curName, FileMode.Open);
...
catch (FileNotFoundException e){
Console.WriteLine(
"file {0} not found",
e.FileName);
}
catch (IOException){
Console.WriteLine(
"some IO exception
occurred");
}
catch {
Console.WriteLine(
"some unknown error
occurred");
}
finally if (s != null)
s.Close();
}
Как видно из примера, оператор анализирует выход функции чтения из потокового файла. Для обработки вариантов при разборе возможных ошибочных ситуаций используется оператор , в данном примере генерирующий диагностические сообщения. В случае ложности всех -альтернатив выполняется (происходит штатное закрытие файла).
По результатам анализа приведенного фрагмента программы на языке C# рассмотрим основные характеристики обработки
Прежде всего, необходимо отметить то обстоятельство, что в составе оператора проверяются последовательно сверху вниз.
Таким образом, при полном разборе случаев разработчиком программного обеспечения одно из всегда удовлетворяется (естественно, в том случае, если список условий не пуст).
Кроме того, синтаксис языка программирования C# разрешает опустить имя параметра в .
Далее, заметим, что тип должен быть выводим из базового класса System.Exception.
Наконец, важным свойством оператора является тот факт, что при отсутствии явного указания параметра подразумевается System.Exception
Для иллюстрации особенностей механизма обработки System.Exception
Как видно из приведенной таблицы, класс System.Exception представляет собой описание многочисленных объектов и методов, которые контролируют стандартный ход обработки
| Имя свойства или метода | Функции свойства или метода |
|---|---|
| Свойства: | |
e.Message |
сообщение об ошибке в виде строки |
e.StackTrace |
просмотр |
e.Source |
приложение или объект, которые вызвали исключительную ситуацию |
e.TargetSite |
метод объекта, который вызвал исключительную ситуацию |
| ... | |
| Методы: | |
e.ToString() |
возвращает имя исключительной ситуации |
| ... |
При исследовании механизмов обработки
Исходя из вида изученного оператора языка программирования C#, а также из стандартных свойств и методов обработки System.Exception
К неявным источникам null ) указателю и т.д.
Однако для реализации событийно управляемых программ в языке программирования C# существует механизм явной генерации throw (приводим соответствующий фрагмент программы):
throw new FunnyException(10);
class FunnyException : ApplicationException
{
public int errorCode;
public FunnyException(int x){
errorCode = x;
}
}
Как видно из приведенного фрагмента программы, оператор throw реализует явный вызов FunnyException с генерацией кода ошибки.
Заметим, что в силу высокой сложности и гетерогенной природы
Для удобства систематизации, хранения, поиска и анализа
Приведем для сведения небольшой фрагмент сложной структуры иерархии стандартных
Exception
SystemException
ArithmeticException
DivideByZeroException
OverflowException
...
NullReferenceException
IndexOutOfRangeException
InvalidCastException
...
Заметим, что существует еще более общий уровень иерархии SystemException, а именно, уровень Exception.
В данной иерархии
Другим подклассом
Продолжим анализ иерархии
ApplicationException
...// специализированные исключения
...
IOException
FileNotFoundException
DirectoryNotFoundException
...
WebException
...
Отдельный подкласс
Еще одним важным подклассом
Наконец, еще одним подклассом
Рассмотрим особенности реализации механизма реакции на
Поиск
Осуществляется просмотр цепочки вызовов методов в обратном направлении до тех пор, пока не будет найден метод с соответствующим . Если такой метод обнаружить не удается, программа завершается аварийно и выдается
Подчеркнем, что алгоритм поиска
Заметим, что в языке C# не существует различия между помеченными
Несмотря на то, что такой подход в первом приближении представляется удобным, он заведомо приводит к созданию менее устойчивого и безопасного прикладного (и тем более системного) программного кода.
Подводя итоги рассмотрения основных аспектов теории и практики событийно управляемого программирования на языке C#, можно сделать следующие выводы.
Во-первых, как и в объектно-ориентированном программировании,
Во-вторых, событийно ориентированное программирование обеспечивает потенциальную легкость настройки интерфейса пользователя (и его адаптации в процессе работы программы в соответствии с требованиями пользователя).
Кроме того, процедуры
Затем, важным преимуществом программирования, ориентированного на
Далее, необходимо отметить такой позитивный аспект событийного программирования как гибкость реинжиниринга (т.е. разработки в обратном направлении) программного обеспечения. По сути, речь идет о
Именно концептуализация составляет то строгое математическое основание, которое позволяет не только моделировать
Для более подробного самостоятельного ознакомления с тематикой лекции рекомендуется следующий список источников: [ 24, 28, 36, 66-69, 79-81].
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.