prosdo.ru 1
Троелсен.

Отличия языка С# от С++.


  1. switch допускает выбор только одной ветви, каждая ветвь должна заканчиваться break

  2. цикл foreach позволяет последовательно обрабатывать элементы массива, не изменяя их значения. Foreach (тип элемента buffer in имя массива) { операторы цикла }. Может применяться к коллекциям.

  3. все массивы являются динамическими. Имя массива – указатель. Тип элемента [ ] имя массива; память выделяется с помощью операции new. Если многомерный массив то например int [ , ] x. при объявлении массива система генерирует новый класс, унаследованный от абстрактного класса Array и массив создается как объект этого нового класса. Компоненты класса Array доступны любому массиву. Методы и свойства класса Array:

    1. свойство Length (LongLenght) – возвращает количество элементов массива типа int (long int). Для многомерных – возвращает количество элементов по всем размерностям (общее количество)

    2. свойство Rank – возвращает размерность массива

    3. метод public static Array CreaterInstance (Type elementType, int length) позволяет создать массив во время выполнения программы, определяя тип элемента в момент создания массива. Тип элемента можно передать с помощью функции typeof (тип)

    4. метод SetValue ( ) – позволяет задать значения элементов массива

    5. метод GetValue ( ) – позволяет получить значение элемента массива

    6. методы Clone ( ) и Copy ( ) – позволяют сделать копию классов. Первый сам сделает новый массив, а второй копирует значения в другой

    7. метод Sort сортирует массив пузырьковым методом. Если элементы массива – объекты собственных классов, то необходимо реализовать метод CompareTo, обеспечивающий сравнение

    8. метод Clear ( ) – очищает элементы массива

    9. методы Contains ( ), IndexOf ( ) – выполняют линейный поиск, первый возвращает логическое значение, второй – индекс искомого элемента.


Операции.


  • Checked/unchecked – вкл/выкл проверку выхода значения за допустимый диапазон

  • Is – позволяет проверить совместим ли объект с заданным типом

  • As – применяется для явного преобразования типа объектов

  • Sizeof – определяет размер памяти в байтах

  • Typeof – возвращает объект типа.


Типы.

  • Decimal – 128-битные числа, имя – 28 знаков, диапазон: -1*10-28 – 7,9*1028

  • Bool – логический тип, true/false

  • String – строка символов

  • Object – базовый класс, от которого наследуются все внутренние и пользовательские классы.


Пространства имен.

Представляет собой способ организации логически взаимосвязанных классов и других типов. В С# принято каждый класс определять в отдельном файле. Пространство имен объединяет отдельные файлы в некоторую структуру с общей областью видимости. Синтаксис определения пространства имен:

namespace имя пространства

{ определение типов }

Полное имя типа определяется следующим образом: имя_пространства.имя_типа. Такое определение позволяет избежать двусмысленности в программном коде при совпадении имен типов, определенных в разных пространствах. Пространства имен допускают вложенность, в этом случае полное имя типа будет состоять из цепочки всех пространств имен, начиная сверху. Чтобы не переписывать в программе каждый раз полное имя достаточно в начале программы указать используемые пространства имен:

using имя_пространства. Для уникальных имен в этом случае в программе достаточно указать только имя типа.

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

Метод main. Выполнение программы в С# начинается с метода main ( ). Поэтому хотя бы один класс должен иметь статический метод main с типом результата void или int, с которого начинается выполнение программы.


Соглашения об именах в С#.

В С# каждое слово в имени принято писать с заглавной буквы. Для параметров функций и правил полей и членов классов используют «верблюжий» стиль – первая буква в имени пишется строчной, а далее каждое слово с большой буквы.

Классы.

Класс в С# – это ссылочный тип, размещенный в куче. Структура отличается от класса тем, что представляет собой значение, размещенное в стеке. Структура не поддерживает наследования.

Данные – члены класса – это поля, константы, события. Константы, объявленные в классе со словом const ассоциированы с классом. Константа рассматривается как переменная, значение которой не может быть изменено. Если значение константы заранее неизвестно, а в ходе выполнения изменяться не должно, то в этом случае можно использовать статическое поле «только для чтения»: readonly. Значение такого поля можно определить только в конструкторе. События позволяют определить, предусмотрена ли обработка того или иного события конкретным объектом и задать метод, обрабатывающий событие.

Методы.

В отличие от С++ спецификатор доступа должен быть указан у каждого метода, двоеточие не ставится. Все методы объявляются и реализуются внутри класса. Функций вне класса не существует. Параметры могут передаваться как о значению, так и по ссылке. По умолчанию параметры не ссылочного типа передаются по значению. Для передачи по ссылке используется ключевое слово ref, которое записывается и перед соответствующим фактическим параметром. Такой параметр инициализируется до передачи в метод. По ссылке передаются и так называемые выходные параметры, которые сопровождаются словом out. Такие параметры при передаче в метод автоматически инициализируются нулями.

Свойства – это наборы функций, определяющие правила доступа к private-полям.

public тип_свойства имя_свойства

{ get

{ return имя_поля; }

set

{ // код для установки значения поля


имя_поля = value; }}


Конструкторы.

Синтаксически конструктор ничем не отличается от С++. Допускается перегрузка конструкторов. Если в классе несколько конструкторов, то автоматический конструктор не будет сгенерирован. В С# конструктор может иметь любой статус доступа. Однако С# позволяет создавать статические конструкторы без параметров. Такой конструктор сопровождается спецификатором Static и необходим в том случае, если в классе определены статические поля или свойства. Статический конструктор из программного кода никогда не вызывается, вызов его производится автоматически до первого обращения к компоненту класса. У класса может быть только один статический конструктор, который имеет доступ только к статическим членам класса. Если статический конструктор в классе перегружен обычным конструктором без параметров, то компилятор будет различать их по спецификатору static.

Если при наличии нескольких конструкторов в классе один конструктор требует вызова другого конструктора, то используется следующий синтаксис: public имя_класса ([ список_параметров]): this ([ список_параметров])

{ операторы конструктора }

При вызове конструктора базового класса this заменяется на base. Из одного конструктора можно вызвать только один другой конструктор.
Финализаторы.

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

Не относятся к ссылочным типам и не поддерживают наследования, хотя относятся к объектным типам. Для структуры всегда генерируется конструктор без параметров, который нельзя переопределить. Структура размещается в стеке. Задавать значения полей структуры при её определении нельзя. Структуры унаследованы от класса system.object.

Методы классов.


Виртуальные методы в производном классе перекрываются модификатором override. Обычные методы в производном классе перекрываются словом new. Абстрактные методы (чистые виртуальные функции) объявляются с ключевым словом abstract, который записывается после спецификаторов доступа. Класс, содержащий абстрактные методы, также объявляется с тем же словом. Закрытые классы и методы объявляются со словом sealed. От закрытого класса нельзя создать производный класс. Закрытый метод нельзя переопределить в производном классе.

Частичные классы. С# позволяет определять класс, структуру или интерфейс в нескольких файлах. В этом случае в определении класса непосредственно перед словом class следует записать слово partial. Компилятор соберет описание класса в единое целое автоматически.

Статические классы. Если класс содержит только статические компоненты, он может быть определен как статический с помощью слова static перед словом class. Это гарантирует, что к этому классу никогда не будут добавлены не статические члены, и объекты этого класса никогда не будут созданы. Для доступа к членам класса используется имя класса.
Использование управляющих элементов Windows Form.

Пример:

abstract class Figure

{

protected int x, y, sizex, sizey;

public int X

{ get {return x;}

Set {x=value;}

}

Public int Y

{ get {return y;}

Set {y=value;}}

Protected Form F;

Public int SizeX

{ get {return sizex;}

Set { if (value
sizex=value;

else sizex=F.width;

}}

Public int SizeY

{ get {return sizey;}

set {sizey=value;}}

public Figure (int x, int y, int sizex, int sizey)

{ X=x; Y=y; SizeX=sizex; SizeY=sizey; }

~Figure ( ) {}

Public abstract void show (Graphics g);

Public void move (int dx, int dy, Graphics g)


{ X+=dx; Y+=dy; show (g); }};

Class Drop: Figure

{ private Bitmap bmp;

Public Drop (int x, int y, int sizex, int sizey): base (x, y, sizex, sizey)

{ bmp = new Bitmap (@”D:\C#Project\snowflake\Капля.jpg”);

Bmp.MakeTransparent ( ); }

~Drop ( ) {}

Public override void show (Graphics g)

{ g.DrawImage (bmp, X, Y, SizeX, SizeY); }}

Class Snowflake: Figure

{ private Bitmap bmp;

Public Snowflake (int x, int y, int sizex, int sizey): base (x, y, sizex, sizey)

{ bmp = new Bitmap (@”D:\C#Project\snowflake\Снег1.jpg”);

Bmp.MakeTransparent ( ); }

~Snowflake ( ) {}

Public override void show (Graphics g)

{ g.DrawImage (bmp, X, Y, SizeX, SizeY); }}

Public partial class Form1: Form

{ private Figure [] obj;

int count =100;

Graphics g;

Public Form1 ( )

{ InitializeComponent ( );

g=this.CreateGraphics ( );

obj = new Figure [count];

Random rand = new Random ( );

for (int i=0; i
switch (rand.Next (2))

{ case 0: obj[i] = new Drop (rand.Next (this.Width), rand.Next (this.Height), this.Height/50, this.Height/50); break;

case 1: obj[i] = new Snowflake (rand.Next (this.Width), rand.Next (this.Height), this.Height/50, this.Height/50); break; }}

private void toolStripMenuItem1_Click (object sender, ErentArqse)

{ // старт

For (int i=0; i
obj[i].show (g);

timer1.Enable = true; }

private void timer1_Tick (object sender, EventArqse)

{ for (int i=0; i
obj[i].move (0, 2, g); }}

static class Program

{ static void Main ( );

{ Application.EnableVisualStyles ( );

Application.SetCompatiblTextRenderingDefault (false);

Application.Run (new Form1 ( )); }}
22 марта 2012 г.

Обработка событий в С#.

Еще в языке Си был определен указатель на функцию как отдельный тип данных. Каждая функция размещается в ОП при выполнении программы, а следовательно, имеет свой адрес – точку входа, то есть адрес, где начинается исполняемый код этой функции. Известно, что адрес можно сохранять в переменной типа указатель. А для того чтобы указатель можно было разыменовать, необходимо определить тип этого указателя. Указатель, ссылающийся на функцию, определяется следующим образом: тип_результата (*имя_указателя) (спецификация_параметров). Спецификация параметров определяет количество параметров, их типы и порядок следования, имена не указываются. Имя функции рассматривается системой как точка входа в функцию и по сути представляет собой указатель, значение которого можно сохранить в переменной типа указатель на функцию тогда и только тогда, когда тип результата самой функции и её сигнатура совпадают с типом указателя на функцию.

Имя_указателя_на_функцию = имя_функции;

После такого присваивания функция может быть вызвана с помощью указателя, на нее ссылающегося: (*имя_указателя_на_функцию) (список_фактических_параметров);

Указатели на функцию активно используются в событийном управлении в С#. Аналогом указателя на функцию в С# является делегат. Описание делегата – это описание типа указателя на функцию (класса).

Delegate тип_результата имя (список_параметров);

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

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


Event имя_делегата имя_события.

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


  1. формулируем событие

  2. определяем актеров, участвующих в событии: кто инициирует, кто реагирует

  3. определяем информацию о событии

  4. описываем тип события (структуру сообщения)

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

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

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

  8. в классе, реагирующем на событие, определяем функцию – обработчик события.


Рассмотрим в качестве примера событие на регулируемом перекрестке.

Namespace AutoCrossRoad

{ public class AutoEventArgs: EventArgs // сообщение о событии «перемещение автомобиля»

{ public int x, y;

Public int napr;

Public int color; // запрос на цвет светофора

Public AutoEventArgs ( ): base ( ) {}}

public class Auto

{ public Bitmap Ris, Fon;

Public Graphics dc;

Public int X, Y, Napr, Dx, Dy;

Public delegate void AutoEvent (object sender, AutoEventArgs ev);

Public static event AutoEvent MoveEvent;

Public Auto

{………….. }

Public void Show (Graphics g)

{………….}

Public void OnMoveEvent (object sender, AutoEventArgs ev)

{ if (MoveEvent!=null)

MoveEvent (sender, ev); }

Public void Move (Graphics g)


{ AutoEventArgs ev = new AutoEventArgs ( );

OnMoveEvent (this, ev);

If (ev.color!=0)

{ g.DrawImage (Fon, X, Y);

Switch (Napr)

{ case 0: X+=Dx; break;

…………………….. }

g.DrawImage (Ris, X, Y); }}}

public class Svetofor

{ protected int X, Y;

Public int color;

Protected Bitmap [ ] Ris = new Bitmap [4];

Public Svetofor (int x, int y, int _color)

{…………

Form.ChangeSvetofor += new Form1.ActionSvetofor (Form1_ChangeSvetofor);

…………}

Void Form1_ChangeSvetofor (object sender, Form1.SvetoforEventArgs ev)

{ color++;

Color %= 4;

Ev.color = color;

Show ((Form1) sender);

}

Public void Show (Form1 f1);

{ f1.dc.DrawImage (Ris[color], X, Y) }}

Public partial class Form1: Form

{ public class SvetoforEventArgs: EventArgs

{ int color = 0;

Public SvetoforEventArgs ( ): base ( ) { }

Public int Color

{ get { return color; }

Set { color=value; }}}

……………

Public Graphics dc;

……………

Public delegate void ActionSvetofor (object sender, SvetoforEventArgs ev);

Public static event ActionSvetofor ChangeSvetofor;

Public Form1 ( )

{ SvetoforEventArgs ev = new SvetoforEventArgs ( );

…………………

Auto.MoveEvent += new Auto.AutoEvent (Auto_MoveEvent);

…………………}

Void Auto_MoveEvent (object sender, AutoEventArgs ev)

{ ev.color = this.svetofor[0].color; }

Private void timer1_Tich (object sender, EventArgs e)

{ for (int i=0; i
Car[i].Move (dc);

}

Protected void OnChangeSvetofor (object sender, SvetoforEventArgs ev)

{ if (ChangeSvetofor)

ChangeSvetofor (sender, ev); }

Private void Timer2_Tich (object sender, EventArgs e)


{ SvetoforEventArgs ev = new SvetoforEventArgs ( );

OnChangeSvetofor (this, ev); }}
19 апреля 2012 г.

Графика в С#.

GDI+ включает несколько пространств имен, обеспечивающих работу с графическими приложениями. Основное пространство имен – System.Drawing – содержит основные классы для вывода графики

– System.Drawing.Drawing2D – классы для выполнения сложных операций с двумерной графикой.

– System.Drawing.Imaging – классы для работы с графическими изображениями, в том числе с метафайлами.

– System.Drawing.Printing – классы для вывода на принтер и его настройку.

– System.Drawing.Text – инструменты для работы со системными шрифтами.

Основные классы пространства System.Drawing:


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

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

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

  • Color – структура, которая определяет набор статических полей для настройки цвета

  • Point, PointF – структуры для работы с координатами точки (целые/вещественные).

  • Reсtangle, ReсtangleF – структуры, предназначенные для определения прямоугольных областей.

  • Size, SizeF – структуры для работы с размерами прямоугольных областей.

  • Region определяет область, занятую геометрической фигурой.

  • Image – абстрактный базовый класс для классов Bitmap, Icon, Cursor.

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

Для работы с растровыми изображениями используются классы Image, Bitmap и Metafile.

Bmp, gif, jpeg, exif, png, tiff – поддерживаемые форматы. Класс Metafile предназначен для работы с векторными изображениями.


Пример:

// класс Form1

Public partial class Form1 : Form

{ protected Bird b1; // объект «птица»

Private Bitmap fon;

Private Bitmap fon1;

Graphics dc, dcfon1;

Public Form1 ( )

{ InitilizeComponent ( );

Dc = this.CreateGraphics ( ); // от формы

Fon = new Bitmap (“Зима.jpg”);

Fon1 = new Bitmap (“Зима.jpg”);

Dcfon1 = Graphics.FromImage (fon1);

B1 = new Bird (this.ClientRectangle. Left, this.ClientRectangle.Bottom/2, 1, 0, 0.5);

}

…………………….

Private void timer1_Tick (object sender, EventArgs e)

{ b1.move (this);

b1.Draw (dcfon1); // поверх fon1

dc.DrawImage (fon1, 0, 0);

dcfon1.DrawImage (fon, 0, 0); // восстанавливали фон

}}
3 мая 2012 г.

Техническое задание включает в себя: наименование разработки, основание для разработки (учебный план), требования к системе в целом, требования к функциональным характеристикам (функции, которые должны быть реализованы в проекте), требования к информационному обеспечению, требования к лингвистическому обеспечению, требования к техническому обеспечению, требования к ПО.

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

У Graphics есть метод (flip), позволяющий повернуть картинку на любой угол!!!
Struct Rect

Inflate – изменяет прямоугольник с заданным коэффициентом.

Intersect – находит пересечение 2 прямоугольников.

Intersect With – показывает, пересекается ли указанный прямоугольник с текущим.

Contains – определяет, включает ли прямоугольник указанную точку или прямоугольник.
Интерфейсы.

Интерфейсы позволяют определить набор обязательных действий, выполняемых классом без указания способа выполнения этих действий. Реализован интерфейс может быть в классе, при этом реализации подлежат все методы, определенные в интерфейсе. Если класс реализует интерфейс, то в этом классе гарантировано наличие всех методов интерфейса. Один и тот же интерфейс может быть реализован различными классами, и один класс может реализовать несколько интерфейсов, то есть в отношении интерфейсов С# допускает множественное наследование. Помимо методов, определенных в интерфейсах, класс может добавлять собственные методы. Объявляется интерфейс следующим образом:

Interface имя_интерфейса

{ тип имя_метода1 (список параметров);

…………………………………………..

тип имя_методаN (список параметров);

}

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