ТЕМА 30:
C# и .NET Framework
През последните години се прави преход от концепцията за програмиране на отделни системи към създаване на интерактивно мрежово приложение. Пред съвременните езици за програмиране стоят съвършено нови задачи за решение, за които е създаден C# - стъпка в еволюцията. От своите предшественици взема най-доброто и обединява най-новите разработки в областта на езиците за програмиране. C# е взел най-доброто от C++ и Java, освен това в него има елементи като делегати и индескатори, а тъй като C# използва системата .NET Framework, то неговия код е доста преносим и може да се използва при разработката на програмни комплекси в многоезикови среди. Компонентите за програмно осигуряване в C# са съвместими с кода писан на друг .NET език.
.NET Framework Class Library – обширна библиотека. C# е нов език, който се развива и усъвършенства като се добавят нови възможности. Visual Studio .NET + Framework са необходими за работа със C#. C# е разработен от Microsoft за работа в .NET Framework. Той е подходящ и ефективен за писане на Windows приложения, използващи интернет. C# е наследил много полезни възможности на други езици за програмиране (Pascal, Ada) и е свързан със C/C++ и Java. За разбирането на C# е необходимо да се анализира природата на тази връзка.
Езикът C е създаден от Кърнинган и Ричи през 1972г., на C е писан 90% от UNIX, който преди е бил писан на Assembler. От 1980 година C е един от най-използваните езици за структурно програмиране. През 1979 година Бьорн Страустрап разширява C за ООП – C++ (първоначално C with Classes). Фактически C++ е ООП-ориентирана версия на C. Затова след изучаване на C при преход към C++ трябва да се изучат новите му възможности. C++ се използва масово в началото на 90те, а към края вече е най-използван.
Java е създаден през ‘91г. От Sun Microsystems като независим от платформата език, който да се ползва при програмиране за вградени контролери. През ‘93 става очевидно, че технологията за решаването на проблема за преносимостта в малък мащаб може да се реши в голям (интернет). Java създава междуплатформен преносим код. В Java преносимостта се достига чрез транслиране на изходния код на програмата в междинен език наричан байт-код, който се изпълнява от Java Virtual Machine. JVM се реализира лесно и е достъпна за много платформи. Използването на байт-код в JVM радикално се отличава от използването на кодове в C/ C++, които винаги се компилират в изпълним машинен код. Машинния код е свързан с определен процесор и операционна система и, следователно, за да се ползва друга конфигурация е необходимо да се прекомпилира, а Java решава този проблем. Това решение го има и в C#.
Java е създаден на базата на C/C++, има сходен синтаксис, но е несъвместим като код. След появата на Java, C/C++ става общоприет фундамент. JVM решава доста проблеми за преносимостта, но за успешна работа трябва да има взаимодействие на различни езици. За решаване на този проблем Microsoft разработва C#, който е съставна част от общата стратегия .NET на тази фирма. Главен архитект е Андерс Хейлсберг.
Между Java и C# няма пряка връзка и те имат много различия. Едно от много важните въведения на C# се отнася до вградената поддръжка на компонентите за програмно осигуряване включващо елементите. Т.е. C# е компонентно ориентиран език.
.NET определя средата, която поддържа развитието и изпълнението на платформено независими приложения. Важно е да се отбележи, че .NET не е ограничен с платформата на Windows и в бъдеще може да се пренесе на други платформи. C# използва независима от езика среда за изпълнение – CLR – Common Language Runtime. Това е система, която управлява изпълнението на програмата и е част от .NET Framework, която дава преносимост и многоезичност. C# ползва .NET библиотека от класове, която дава достъп до средата за изпълнение.
При компилирането на C# се получава неизпълним, междинен език на Microsoft – Microsoft Intermediate Language (MSIL) подобен на псевдокод. Междинният език определя набор от преносими команди независими от процесора. MSIL прилича на байт-кода на Java, но има различия. .NET транслира междинния код в изпълним по време на изпълнение на програмата. Програмата на MSIL се транслира в изпълним код с използване на just-in-time компилатор. При изпълнение на .NET програма се активира just-in-time компилатор, който транслира не цялата програма, части от нея се транслират при необходимост. При компилиране на C# програмата, освен програма на MSIL, се получават метаданни описващи данните използвани в програмата, което позволява използването на различни езици.
Обектно-ориентирано програмиране. Примерна програма
Езикът C# се базира на принципите на ООП и всички C# програми са в някаква степен обектно-ориентирани. При структурното програмиране кодът въздейства на данните, при ООП типът на данните задава вида на операциите, които могат да бъдат приложени към тях. За поддържането на принципите на ООП, всички ООП езици, включително C#, имат 3 общи черти – инкапсулация, полиморфизъм и наследяване.
Инкапсулацията е механизъм за програмиране, обединяващ в едно код и данни, които той обработва, а също така ограничава от външен достъп и неправилно използване. В обектно-ориентираните езици кодът и всички данни могат да се свържат така, че да се създаде автономна структура, наречена обект. С други думи обектът е структура, която поддържа инкапсулацията. В границите на обекта, кодът и данните могат да бъдат закрити или открити. Закритите входни данни са известни и достъпни само от други части на същия обект, т.е. към закрития код и данни не може да има достъп от онези части от програмата, които са извън границите на обекта. Когато кодът и данните са открити, то другите части могат да работят с тях. Обикновено частите на обекта, които са открити правят интерфейс. В C# класът е основна инкапсулационна структура, специфицираща данните и кодът, работещ с тях.
C# използва спецификацията на класа за конструиране на обекта – екземпляр на класа, следователно класът е набор от инструкции, в които е оказано как трябва да бъде създаден обект. Кодът и данните се наричат членове на класа. Данните в обекта, определени от класа, се наричат променливи на екземпляра, фрагментите от кода, които работят с тези данни се наричат методи. В C# термина „метод” е възприет за подпрограми, които в C/C++ се наричат функции. Понеже C# е пряк наследник на C++, то в C# понякога се използва термина ‘функция”.
Полиморфизмът е свойство, което позволява на няколко обекта, имащи някои общи характеристики, да получат достъп до един интерфейс и да реализират упоменатите в него методи. Например стек, може да се работи с програма, която изисква 3 стека от различни типове – цял, реален, символен. В този случай за реализацията на всеки стек се използва един и същи алгоритъм, въпреки че съхраняваните данни са от различен тип. В необектно-ориентираните езици трябва да бъдат създадени 3 различни набора от стекове и процедури. В C# чрез полиморфизъм може да се реализира един общ набор подходящ за работа с трите стека. По такъв начин, определяйки методи, които се използват за един тип стек, те могат да бъдат използвани и за другите типове. Концепцията за полиморфизъм е – един интерфейс, множество от методи. Това означава, че за група сходни процеси може да се създаде унифициран интерфейс. Полиморфизмът позволява да се намали сложността на програмите чрез използване на единен интерфейс за специализация на общ клас от действия. Компилаторът, чрез създадената програма, автоматично избира специфично действие вместо това програмистът да го прави ръчно. Програмистът трябва само да реализира изпълнимите методи.
Наследяването е средство, с помощта на което един обект може да получи свойствата на друг. Без наследяване всеки обект трябва да определи всички свои характеристики. С наследяване обектът трябва да определи само тези качества, които го правят уникален в рамките на този клас. Той може да наследява свойствата на родителските си обекти, което дава възможност на един обект да бъде специфичен екземпляр на своя клас.
Създаването на програма минава през 3 етапа:
- Първичен файл на C#;
- Компилиране;
- Изпълнение.
Прието е файлът с програмата на C# да има разширение .cs. За работа при някой други езици за програмиране (Java) името на файла е произволно, но много програмисти предпочитат да се казва както главния клас. Компилаторът транслира C# в междинен език. Изпълнението на програмата става под управлението на независима от езика среда за програмиране, която при нужда стартира JIT компилатор, който при нужда транслира части от програмата от междинен в машинен език и ги изпълнява.
В програмата се преобразува стойността от Фаренхайт в Целзий, има едноредови и многоредови коментари. Коментарите обикновено обясняват как работят определени части от програмата и какво съдържат определени елементи.
/*Програма за извеждане на таблица със стойността на температурата по скалата на Фаренхайт и съответните й стойности по скалата на Целзий*/
using System;
/*Програмата използва пространството от имена System за методите, асоциирани с библиотеката от класове в .NET Framework*/
class FtoCTable
{
public static void Main()
{
double f, c;
int counter;
counter = 0;
for (f = 0.0; f < 100.0; f++)
{
//преобразуване в градуси по Целзий
c = 5.0 / 9.0 * (f - 32.0);
Console.WriteLine(f + " градуса по скалата на Фаренхайт са равни на " + c + " градуса по скалата на Целзий.");
counter++;
//след всеки 10 реда извеждаме празен ред
if (counter == 10)
{
Console.WriteLine();
counter = 0;
}
}
}
}
Дефинирането на класа започва с отваряща скоба „{” и завършва с затваряща „}”. Елементите между двете скоби се наричат членове на класа. В C# всички процеси в програмата се извършват в границите на класа. Всички приложения на C# започват от метода Main, аналогично на програма на C/ C++, която започва да се изпълнява с извикване на main. Ключовата дума public е спецификатор/модификатор за достъп. Модификаторът определя как другите части на програмата може да достъпват членовете на класа. Ако имаме public – то имаме достъп от извън класа, private – не позволява пряко използване на членове от класа от кода, който е определен извън този клас. В разглежданата програма Main() е public, тъй като при стартиране ще бъде извикан от операционната система. В C# не се изисква Main() да е public, но е прието.
Ключовата дума static позволява да се извика метода Main() преди да бъде създаден обект от неговия клас, тъй като той се вика при стартиране на програмата, то той трябва да е static. Ключовата дума void показва, че Main не връща стойност. Празните скоби след него значат, че не приема аргументи. Кодът на Main е в { }, WriteLine е вграден метод за извеждане на екрана на монитора, Console е вграден клас за вход и изход. Точката между двете съобщава, че метода WriteLine е член на класа Console. В C# всяка операция завършва с „;”, главните и малки букви са различни. Компилаторът извежда съобщения за грешки по време на компилация, които са най-често синтактични; някой съобщения може да са подвеждащи и мястото на грешката може да не е посоченото. В C# е възможно да се определи името на класа/метода като се използва името на нивото, където е дефиниран.
Пример:
Console.WriteLine == System.Console.WriteLine
Променливата е име на поле от оперативната памет, което е последователност от един или няколко байта, в него се записва стойността на променливата. По време на изпълнение тази стойност може да бъде променяна. В C# всички променливи трябва да бъдат дефинирани преди тяхното използване. Общ вид на дефиницията:
тип списък_от_имена_на_променливи;
Типът определя множеството от допустимите стойности на променливата. В C# операцията за присвояване (=) копира стойността, стояща отдясно на знака, в променливата стояща отляво.
В метода WriteLine може да се използва операцията знак „+” която свързва заедно произволен брой елементи (конкатенация). Както в много други езици за програмиране, така и в C# има аритметичния набор от операции. Вградения метод Write е сходен на метода WriteLine, без да се минава на нов ред след всяко извикване. За числа с плаваща точка в C# има 2 типа – float и double, при които числата се представят с обикновена или двойна точка. По-често се използва double. Само за минаване на нов ред се използва метода WriteLine(); без аргументи. В тялото на метода операторите се изпълняват последователно отгоре надолу (в реда на записване). Този ред може да се променя с използване на различни оператори в C# - if.
В булевите изрази могат да се използват следните операции за отношение <, >, <=, >=, ==, !=.
Последователност от 2 или повече оператора, заключени във фигурни скоби, се нарича съставен оператор или блок. Съставния оператор може да се използва по същия начин като единичен оператор.Той често се използва в операторите if и for. Използването на блокове не води до увеличаване на времето за изпълнение, но може да доведе до опростяване на определен алгоритъм, което води до увеличаване на скоростта и ефективността на програмата. Както вече казахме, всеки отделен оператор завършва с „;” обаче съставните оператори не завършват с „;” тъй като завършват с „}”. В C# понятието ред не се използва за определяне на синтаксиса на една програма и затова „;” може да се използва на произволно място в реда и в частност някъде може да няма „;” – това дава възможност за нагледно, ясно и разбираемо оформяне на текста на програмата.
В C# има 77 ключови думи, които не могат да се използват като имена на променливи, класове и методи. Както в C++, в C# ключовите думи съдържат само малки букви, към буквите е причислен и символа „_”. Хубав стил на програмиране е използването на мнемонични идентификатори. В C# може да се започва и с „@”. Библиотеката от класове на .NET Framework се използва в C# за реализация на операциите за вход и изход, обработка на низове, работа в мрежа, графичен интерфейс и др. Библиотеката осигурява повечето от функционалните възможности използвани във всяка програма на C#.