Идентификатори
Идентификаторите в С# се състоят от последователности от букви, цифри и знак за подчертаване като винаги започват с буква или знак за подчертаване. В тях малките и главните букви се различават. Идентификаторите могат да съдържат Unicode символи, например:
Microsoft препоръчва се следната конвенция за именуване:
- PascalCase – за имена на класове, пространства от имена, структури, типове, методи, свойства, константи
- camelCase – за имена на променливи и параметри
Въпреки, че е възможно, не се препоръчва да се използват идентификатори на кирилица или друга азбука, различна от латинската.
Декларации
Декларациите на променливи в C# могат да са няколко вида (почти като в C++, Java и Delphi) – локални променливи (за даден блок), член-променливи на типа и константи. Ето пример:
Член-променливите могат да имат модификатори, например:
Константи
Константите в С# биват два вида – константи, които приемат стойността си по време на компилация (compile-time константи) и такива, които получават стойност по време на изпълнение на програмата (runtime константи).
Compile-time константи
Compile-time константите се декларират със запазената дума const. Те задължително се инициализират в момента на декларирането им и не могат да се променят след това. Те реално не съществуват като променливи в програмата. По време на компилация се заместват със стойността им. Например:
Runtime константи
Runtime константите се декларират като полета с модификатора readonly. Представляват полета на типа, които са само за четене. Инициализират се по време на изпълнение (в момента на деклариране или в конструктора на типа) и не могат да се променят след като веднъж са инициализирани. Например:
Оператори
Операторите в С# са много близки до операторите в C++ и Java и имат същите действие и приоритет. Те биват:
- Аритметични: +, -, *, /, %, ++, --
- Логически: &&, ||, !, ^, true, false
- Побитови операции: &, |, ^, ~, <<, >>
- За слепване на символни низове: +
- За сравнение: ==, !=, <, >, <=, >=
- За присвояване: =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
- За работа с типове: as, is, sizeof, typeof
- Други: ., [], (), ?:, new, checked, unchecked, unsafe
В C# операторите могат да се предефинират. В темата "Обектно-ориентирано програмиране в .NET" ще видим как точно става това.
Изрази (expressions)
Програмен код, който се изчислява до някаква стойност, се нарича израз (expression). Изразите в C# имат синтаксиса на C++ и Java. Например:
Програмни конструкции (statements)
Програмните конструкции (statements) имат синтаксиса на C++ и Java. Те биват няколко вида:
Елементарни програмни конструкции
Елементарните програмни конструкции са най-простите елементи на програмата. Например:
Съставни конструкции
Съставните програмни конструкции се състоят от няколко други конструкции, оградени в блок. Например:
Програмни конструкции за управление
Конструкциите за управление, както в повечето езици за програмиране, биват условни конструкции, конструкции за цикъл, за преход и т. н. В C# синтаксисът на тези конструкции е много близък до синтаксиса на C++ и Java.
Условни конструкции (conditional statements)
Условните конструкции в С# са if, if-else и switch. Техният синтаксис е еднакъв със синтаксиса им в C, C++ и Java.
if и if-else конструкциите за разлика от С и С++ могат да приемат единствено булево условие. Не са позволени целочислени стойности, които да играят ролята на true, ако са различни от 0 и false – иначе. Ето няколко примера за условна конструкция:
Ново в switch конструкцията за разлика от C и C++ е, че позволява изразът, по който се осъществява условието, да бъде от тип string или enum. Например:
Конструкцията switch се различава от реализацията си в С++. В С# не се разрешава "пропадане" (fall-through). Пропадането в switch конструкциите може да доведе до грешки. Независимо от удобствата, които предлага тази възможност, дизайнерите на езика С# са преценили, че рискът за грешка поради пропускане на break е по-голям, затова всеки case етикет трябва задължително да завършва с break.
Конструкции за повторение и цикъл
Конструкциите за повторение (iteration statements) са for-цикъл, while-цикъл, цикъл do-while и цикъл foreach – за обработка на колекции. Техният синтаксис е еднакъв със синтаксиса им в C, C++ и Java. Изключение прави foreach цикълът, който няма еквивалент в C и C++. Ето няколко примера:
Пример за for-цикъл:
Пример за while-цикъл:
Пример за цикъл do-while:
Операторът foreach е приложим за масиви, колекции и други типове, които поддържат интерфейса IEnumerable или имaт метод за извличане на итератор (enumerator).
Пример за цикъл foreach:
Конструкции за преход
Конструкциите за преход в C# са: break, continue – които се използват в цикли, goto – за безусловен преход и return – за връщане от метод. Те работят по същия начин, като в C, C++ и Java.
Пример за използване на конструкцията break:
Конструкции за управление на изключенията
Конструкциите за управление на изключенията в С# са: throw – за предизвикване на изключение, try-catch – за прихващане на изключение, try-finally – за сигурно изпълнение на завършваща секция и try-catch-finally – за прихващане на изключение със завършваща секция.
Пример за предизвикване и прихващане на изключение:
Методът ThrowException() предизвиква изключение от тип Exception, което може да бъде прихванато, ако функцията, която го предизвиква, се намира в try-catch блок. В такъв случай може да се извършат действия в catch блока, в зависимост от информацията, която носи това изключение.
Конструкциите try-finally и try-catch-finally се използват най-вече за освобождаване на ресурси, които се използват в тялото им. Независимо дали възникне изключение при работата с даден ресурс, той трябва да бъде освободен накрая – това обикновено се прави във finally блок, който се изпълнява независимо дали се минава през catch блока. Блокът finally се изпълнява дори и да има return в catch или try блок.
В темата "Управление на изключенията в .NET" ще разгледаме подробно работата с изключения, техните особености и препоръките за правилна работа с тях.
Специални конструкции
Специалните конструкции в С# са: lock – за синхронизирано изпълнение, checked, unchecked – за контрол на аритметичните препълвания, unsafe – за директен достъп до паметта чрез указатели, fixed – за фиксиране на местоположението в паметта при работа с неуправляван код.
Коментари в програмата
Коментарите биват два вида - коментар за част от програмен ред и блоков коментар.
Ето пример за коментар на един ред:
Ето пример и за блоков коментар:
Вход и изход от конзолата
В .NET Framework за вход и изход от конзолата се използват стандартни класове от BCL (Base Class Library). Входът и изходът от конзолата се осъществяват чрез класа Console, намиращ се в пространство от имена System.
Класът System.Console предоставя основната функционалност, от която се нуждаят конзолните приложения (console applications), които четат и пишат на екрана. Ако конзолата не съществува (например в Windows Forms и уеб-базираните приложения), писането в конзолата няма никакъв ефект и не се предизвикват изключения.
Всяко конзолно приложение при стартиране получава от операционната система три стандартни потока – за вход, изход и за грешки. При изпълнение от конзолата тези три потока автоматично се асоциират със самата нея. За достъп до стандартния вход, стандартния изход и стандартния изход за грешки в .NET Framework се използват свойствата In, Out и Error на класа Console.
Вход от конзолата
Входът от конзолата се осъществява чрез два метода на класа Console - Read() и ReadLine(). Методът Read() чете единичен символ от стандартния вход и го връща като int стойност или връща -1, ако няма повече символи. Методът ReadLine() чете цял символен ред и връща string или стойност null ако е достигнат края на входа.
И двата метода са синхронни (блокиращи) операции т. е. при извикване блокират, докато не бъде прочетен някакъв символ (ред).
Методът Read() има една особеност – той не връща управлението след всеки въведен символ, а връща прочетените символи наведнъж един след друг едва след като се натисне [Enter]. По тази причина този метод не е удобен за интерактивен вход от клавиатурата при конзолни приложения.
Вход от конзолата – примери
Ето един пример за използването на метода Read():
В практиката за въвеждане на стойности от конзолата по-често се използва методът ReadLine(). Ето пример за неговата употреба:
Изход към конзолата
Изходът към конзолата се осъществява чрез два метода на класа Console - Write(…) и WriteLine(…), които печатат на конзолата подадените като параметри данни, с разликата, че WriteLine(…) преминава на нов ред след като отпечата текста. Методите приемат string, int, float, double и други типове данни.
Write(…) и WriteLine(…) приемат и параметрични форматиращи низове, които позволяват печатане на текст чрез шаблони, които се попълват от подадените параметри. На форматиращите низове ще обърнем специално внимание в темата "Символни низове".
Изход на конзолата – пример
Ето един пример за вход и изход от конзолата, който илюстрира и използването на форматиращи низове:
Дебъгерът на Visual Studio .NET
Сега ще илюстрираме как се използва дебъгерът на Visual Studio .NET. Ще покажем поставяне на точка за спиране (breakpoint), изпълнение на програмата в дебъг режим, проследяване на изпълнението на програмата и следене на стойностите на променливите по време на изпълнение.
Ще си поставим за задача да напишем програма, която намира всички трицифрени числа, сумата от цифрите на които е стойността 25. Можем да решим задачата по следния начин:
За да проследим изпълнението на примерната програма, ще изпълним следните стъпки:
1. Стартираме Visual Studio .NET.
2. Създаваме ново конзолно приложение с име Digits.sln. Въвеждаме в него сорс кода от примера Digist.cs.
3. За да го компилираме натискаме [Shift]+[Ctrl]+[B].
4. Слагаме точка на прекъсване (breakpoint) с мишката върху първия ред от най-вътрешния програмен блок (щракваме малко вляво от самия ред и редът се маркира по специфичен начин):
5. Стартираме програмата от съответния бутон за стартиране от лентата с инструменти на Visual Studio .NET. Програмата ще започне да се изпълнява и когато се достигне реда с точката на прекъсване, Visual Studio .NET ще спре изпълнението и ще влезе в дебъг режим.
6. От менюто Debug можем да разгледаме по-интересните функции на дебъгера на Visual Studio .NET. Можем да добавим точки на прекъсване (breakpoints), да следим стойностите на променливите, да проследяване на изпълнението на кода по различен начин (Step Into, Step over, Step out), да добавим променливи за следене (Add Watch), да следим стека за изпълнение на програмата и т.н. Можем да разгледаме представянето на променливите в паметта – като изберем Debug | Windows | Memory. Много полезен е и прозорецът Command Window, в който не само може да се види стойност на променлива в дебъг режим, но и да се изпълни някакъв метод и да се види върнатата от него стойност. С [Shift] + [F9] при маркирана променлива може да се извика прозорец за нейното наблюдение (Quick Watch).
Точките на прекъсване могат да бъдат асоциирани с някакво условие (conditional breakpoints) и да спират изпълнението на програмата само ако това условие е истина.
Ето как изглежда работното пространство на Visual Studio .NET по време на проследяване на изпълнението на програмата след спиране в точката на прекъсване и преминаване към следващия оператор с [F10]:
Инструментът ILDASM
Всяка програма на С# се компилира до междинен език IL (Intermediate Language). Microsoft предоставя стандартен инструмент за разглеждане на този, генериран от компилаторите на С#, код. Това е инструментът Microsoft .NET Framework Disassembler (ILDASM). С тази деасемблираща програма можем да отворим всяко .NET асембли и да разгледаме неговите пространства от имена, класове, типове и код.
Инструментът ildasm.exe е стандартна част от Microsoft .NET Framework SDK. Обикновено .NET Framework SDK идва заедно с Visual Studio .NET и се намира в директория C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin. Нека илюстрираме как се използва той. За целта трябва да изпълним следните стъпки:
1. Стартираме командния интерпретатор cmd.exe:
2. Отиваме в директорията, където се намира компилираната програма, например, програмата от предходния пример Digits.exe:
Извикваме от командната линия инструмента ILDASM (ildasm.exe) и му подаваме като параметър компилираната програма Digits.exe:
4. Навигирайки по дървото, което ILDASM показва за асемблито Digits.exe, можем да видим как изглежда MSIL кодът за конструктора на класа Digits и за метода му Main():
XML документация в C#
XML документацията в C# програмите представлява съвкупност от коментари, започващи с "/ / /". Тя може да съдържа различни XML тагове – например, таг описващ връщана стойност на метод, таг за препратки към други методи и др. Като идея XML документацията прилича на JavaDoc в Java.
XML документацията значително улеснява поддръжката – документацията е част от кода, а не стои във външен файл. Поддържа се лесно и ползата от нея е видима още при разработката на приложението – Visual Studio .NET показва краткото описание на даден метод, ако той е документиран чрез вградената XML документация, при задействане на IntelliSense. C# компилаторът може да извлича XML документацията като XML файл за по-нататъшна обработка.
Ето пример за използване на XML документация:
Тагове в XML документацията
Ето по-важните тагове, използвани в XML документацията в C#:
- <summary>…</summary> – кратко описание за какво се отнася даден тип, метод, свойство и т.н. Visual Studio .NET показва това описание при задействане на IntelliSense.
- <remarks>…</remarks> – подробно описание на даден тип, метод, свойство и т.н. Visual Studio .NET показва това описание в областта Object Browser.
- <param>…</param> – описание на един от параметрите на даден метод.
- <returns>…</returns> – описание на връщаната от даден метод стойност.
- <exception>…</exception> – описание на изключение, което може да възникне в даден метод.
- <seealso> – препратка към информация, свързана с текущото описание.
- <value>…</value> – описание на свойство (property).
Извличане на XML документация от C# сорс код
Сега ще покажем как чрез C# компилатора може да се извлече документацията от C# файл в отделен XML файл. Нека имаме следната програма на C#, която използва XML документация:
За да извлечем документацията от тази програма, трябва да изпълним следните стъпки:
1. Стартираме командния интерпретатор cmd.exe:
2. Отиваме в директорията, където се намира сорс кода на програмата. Нека тя е Demo-6-XML-Comments:
3. Извикваме компилатора на C#, за да компилира файла MainClass.cs, като му задаваме опцията за извличане на XML документацията в отделен файл:
4. Отваряме получения .xml файл с Internet Explorer, за да разгледаме съдържанието му.
Ето как полученият XML файл:
Генериране на HTML документация от VS.NET
Сега ще покажем как чрез Visual Studio .NET може да се генерира HTML документация за даден проект на C# по XML коментарите в неговия сорс код. Във вид на HTML документацията е много по-удобна за четене и разглеждане.
За целта трябва да изпълним следните стъпки:
1. Отваряме с Visual Studio .NET проект, в който сме използвали XML документиране, например проекта Demo-6-XML-Comments.sln, който съдържа кода от предходния пример.
2. От меню Tools избираме Build Comment Web Pages…. Указваме директория, където да се генерира HTML документацията, и натискаме бутона [OK]. Visual Studio .NET ще генерира в посочената директория съвкупност от HTML файлове, които документират нашия проект и съдържат XML коментарите от сорс кода му, подредени в подходящ за разглеждане вид.
3. Разглеждаме HTML документацията, която Visual Studio .NET е генерирал. Можем да навигираме по пространствата от имена, типовете от проекта и отделните му методи:
Директиви на предпроцесора
Нека сега разгледаме някои по-важни директиви на т. нар. предпроцесор. Преди компилация C# програмите преминават през процес на обработка, който идентифицира кода, който трябва да бъде компилиран при условна компилация. Този процес се изпълнява от предпроцесора. Програмно върху предпроцесора можем да указваме влияние чрез т.нар. директиви – запазени думи, започващи със символа #.
Директиви за форматиране на сорс кода
В С# са въведени директиви за форматиране на сорс кода - #region и #endregion, които ограждат блок от кода, който се "свива" от редактора на Visual Studio .NET:
[img]http://i.data.bg/07/07/21/471102_orig.jpg[img]
Visual Studio .NET редакторът много често слага региони, за да отдели автоматично-генерирания код от сорс кода, писан от програмиста. Директивите #region и #endregion се игнорират от C# компилатора и се използват единствено от средите за разработка.
Директиви за условна компилация
Директивите #define и #ifdef служат за условна компилация. Чрез тях може да се укаже на компилатора да компилира кода по различен начин според процесора, платформата и въобще средата, в която се извършва компилацията. Чрез #if, #else, #elif, #endif се задават границите на блоковете за условна компилация и съответните условия (знаци) за компилиране. Директивите #define и #undef дефинират знаци за условна компилация, според които се определя кой от блоковете за условна компилация да се разглежда.
Условна компилация – пример
Следният пример показва как могат да се използват директивите на предпроцесора за условна компилация:
Ето и резултата от изпълнението на примера:
Директиви за контрол над компилатора
Директивите #warning и #error предизвикват предупреждения и грешки по време на компилация. Например следната програма на C# се компилира успешно, но с предупреждение:
Документацията на .NET Framework
Програмирането с .NET Framework е немислимо без неговата документация. Затова нека сега разгледаме какво представлява тя и как можем да я използваме при търсене на помощна информация по време на разработката на .NET приложения.
MSDN Library
Документацията на .NET Framework се съдържа в "Microsoft MSDN Library".
MSDN Library е система, която предоставя пълен набор от технически документи, описващи продуктите, инструментите и технологиите за разработка на Microsoft (в частност .NET Framework и C#), както и средства за навигация и търсене в тях. MSDN Library съдържа технически ръководства, справочна информация, статии, примери и други ресурси за софтуерни разработчици.
MSDN Library е достъпен безплатно в on-line вариант от Интернет сайта за разработчици на Microsoft –
http://msdn.microsoft.com/library/. Продуктът се разпространява и за локална инсталация заедно с партньорските програми на Microsoft.
MSDN Library – пример
За пример ще покажем как можем да намерим подробна информация за форматиращите низове в .NET Framework и тяхното използване. За целта стартираме MSDN Library и търсим "composite formatting":
.NET Framework и MSDN Library
Документацията на .NET Framework е част от MSDN Library и се разпространява заедно с VS.NET и .NET Framework SDK.
Когато бъде инсталирана, документацията за .NET Framework, тя се интегрира във VS.NET и може да се използва директно от него. Например, ако се нуждаем от помощна информация за метода WriteLine(…) на класа Console, натискаме [F1] във Visual Studio .NET докато курсорът е върху този метод. Отваря се нов прозорец, в който са описани параметрите, типа на връщаната стойност, типовете изключения, които може да предизвика описвания метод, в кое пространство от имена се намира и др.
Ето как изглежда описанието на метода WriteLine(…) на класа Console:
Източник:
Светлин Наков и колектив
Глава III