Sunteți pe pagina 1din 63

Elemente de bază ale

limbajului C#
Cuprins
• Entităţi sintactice de bază
• Instrucţiuni
• Directive preprocesor
• Directiva using

2
Entităţi sintactice de bază

Identificatori
– Sunt secvenţe de caractere folosite pentru
nume de constante, tipuri de date, variabile
sau funcţii
– Un identificator este compus dintr-un singur
cuvânt, format din caractere Unicode şi poate
începe numai cu o literă sau cu caracterul
underscore (_)
– Identificatorii trebuie să difere de cuvintele
cheie
3
Identificatori

– Dacă, totuşi, este posibil ca un identificator să


coincidă cu un cuvânt cheie (de exemplu din alt
limbaj) trebuie utilizat caracterul @ ca şi prefix:
• un astfel de identificator se numeşte identificator verbatim
• caracterul @ nu face parte efectiv din identificator, astfel că,
în alte limbaje, identificatorul este văzut ca un identificator
normal
– Identificatorii ce încep cu secvenţe de două caractere
underscore (__) se folosesc pentru implementarea
limbajului
• ca urmare, nu pot fi folosiţi în programe

4
Cuvinte cheie (keywords)
• Sunt secvenţe de caractere rezervate pentru
declaraţii de date şi pentru instrucţiuni

• Nu pot fi folosite pentru identificatori (cu excepţia


dată de caracterul @)

• Toate cuvintele cheie folosesc litere mici

• Limbajul C# face distincţie între litere mici şi


litere mari (este "case-sensitive")

5
Literali

• Permit reprezentarea unor valori în program

• Pot avea următoarele tipuri:


– boolean,
– întreg,
– real,
– caracter,
– şir,
– null

• Literali booleni: true, false


6
Literali
• Literali întregi:
– numere întregi, în baza 10 sau 16 (prefix 0x, 0X)
– se pot folosi sufixele u,U (unsigned) sau l,L(long)

• Literali reali:
– se folosesc pentru valori de tipul float, double şi
decimal
– se poate folosi notaţia zecimală
(parte_întreagă.parte_fracţionară)
– sau cea ştiinţifică (cu exponent)
– sufixele permise sunt f, F, d, D, m, M (decimal-
reprezentarea cu 29 zecimale pentru calcule
financiare)
7
Literali

• Literali caractere:
– reprezintă un caracter Unicode
– posibilităţi:
• de obicei dintr-un caracter delimitat de apostrofuri (de
exemplu ‘x’)
• din secvenţe de evitare simple (\’, \n, \t, …), caz în care se
generează un caracter Unicode pe baza unui tabel de
corespondenţe
• secvenţe de evitare în hexazecimal (\x hex-digit), caz în care
caracterul este dat de corpul secvenţei

8
Literali

• Literali şir de caractere:


– pot fi de două tipuri, regulate şi verbatim
– un şir regulat de caractere constă dintr-o secvenţă
(posibil vidă) de caractere delimitată de ghilimele
• secvenţa poate include şi secvenţe de evitare

– un şir verbatim constă din caracterul @ urmat de un


şir regulat (de exemplu @”hello”) şi poate continua
pe mai multe linii

• Literalul null:
– are o singură valoare posibilă, null

9
Operatori
Categorie Operatori Asociativitate
Primari x.y, x?.y, f(x), a[x], a?[x], x++, x--, S->D
new, typeof, checked, unchecked
Unari +, -, !, ~, ++x, --x, (T)x D->S
Multiplicativi *, /, % S->D
Aditivi +, - S->D
Shiftare <<, >> S->D
Relaţionali şi de <, >, <=, >=, is, as S->D
testare a tipului
Egalitate ==, != S->D
Logici pe biţi &, ^, | S->D
Logici pe &&, || S->D
operand
Condiţionali x ?? y, ?: D->S
Atribuire =, *=, /=, %=, +=, -=, <<=, >>=, &=, D->S
^=, |=

10
Operatori

• typeof:
– are ca rezultat tipul operandului
• checked:
– are ca efect generarea unei excepţii
(OverflowException) dacă, în timpul execuţiei,
valoarea unei expresii de tip întreg depăşeşte
domeniul de valori al acelui tip
• unchecked:
– are ca efect invalidarea verificărilor aritmetice în
etapa de compilare (mai rar utilizat)

11
Operatori

• is:
– se foloseşte pentru a verifica, în timpul execuţiei,
dacă tipul unui obiect este compatibil cu un tip dat
– utilizare: expresie is Tip
– rezultatul este o valoare booleană (true sau false)
– în evaluarea tipului expresiei se iau în considerare şi
conversii, exclusiv cele definite de utilizator

• as:
– se foloseşte pentru a face conversii explicite între o
valoare şi un tip referinţă, însă fără a genera o
excepţie (aşa cum face operatorul cast, în cazul unor
situaţii anormale)
– utilizare: expresie as Tip
– rezultatul este valoarea convertită sau valoarea null în
caz de eşec 12
Operatori

• x?.y (null conditional)


– dacă x este nenul se accesează membrul y, altfel
rezultatul este valoarea null

• a?[x] (null conditional)


– dacă a este nenul se face accesul pe baza indexului
x, altfel rezultatul este valoarea null

• x ?? y (null coalescing)
– dacă x este nenul rezultatul este x, altfel rezultatul
este y

13
Operatori

• Se remarcă lipsa operatorului C++ delete,


pentru dealocarea obiectelor dinamice:
– C# asigură managementul automat al memoriei:
• obiectele dinamice (create cu operatorul new) sunt
automat distruse atunci când nu mai sunt referite

• presupune cod suplimentar adăugat de compilator:


– care (se pare) nu influenţează serios performanţele
– însă presupune şi o degrevare a utilizatorului de
grija dealocării obiectelor

• presupune şi alte manevre în memorie (mutarea


obiectelor) pentru crearea unor zone libere contigue
14
Tipuri
• Un program C# constă din:
– crearea unor tipuri noi
– utilizarea unor tipuri existente:
• predefinite sau importate din alte biblioteci

• Fiecare tip conţine un set de date şi funcţii


(metode) membre, împreună formând module ce
sunt elementele de bază ale unui program C#

• In general, pentru a utiliza un tip, trebuie create


instanţe ale acelui tip:
– acei membri (date şi funcţii) care necesită instanţiere
se numesc membri instanţă
– acei membri care pot fi utilizaţi numai pe baza tipului
se numesc membri statici
15
Tipuri

• Fiecare tip are un set propriu de reguli ce


definesc cum poate fi convertit acel tip către alt
tip sau invers

• Conversiile între tipuri pot fi:


• implicite (se fac automat)
• explicite (operatorul de conversie explicită cast)

• Conversiile implicite asigură că nu se pierd date


în cursul conversiei:
– sunt permise conversii implicite de la un tip cu
domeniul mai mic către un tip cu domeniul mai mare
– în caz contrar este necesară o conversie explicită 16
Categorii de tipuri
• Tipul valoare:
– corespunde tipurilor de bază:
• tipurile simple (int, long, bool, etc.),
• structuri şi enumerări

• Tipul referinţă:
– corespunde unor tipuri cu funcţionalitate extinsă:
• clasă, tablou, delegări, interfeţe şi tipul string

• Tipul pointer:
– este utilizat numai pentru manipularea explicită a
memoriei în aşa numitele blocuri nesigure (unsafe
blocks)
17
Categorii de tipuri

• Principala deosebire între tipul valoare şi tipul


referinţă constă în modul în care acestea sunt
reprezentate în memorie
– Pentru tipul valoare:
• se păstrează în memorie o valoare brută (numerică, caracter,
…), valoare ce este depusă, de obicei, pe stivă

– Pentru tipul referinţă:


• se stochează în memorie adresa unui obiect din memoria
heap
• tipul referinţă poate avea valoarea null, caz în care nu
adresează nici un obiect
• acest tip este creat folosind operatorul new, dar nu este
necesară utilizarea operatorului delete
18
Tipuri predefinite

• Categorii:
– tipuri valoare:
• întreg, real, decimal, char, bool
– tipuri referinţă:
• object, string

• Aceste tipuri au şi alte nume (alias) introduse în


spaţiul de nume System

19
Tipurile întregi:

Tip C# Tip System Tip Nr. biţi Domeniu de valori


sbyte System.Sbyte sbyte 8 -128 ÷ 127

short System.Int16 byte 8 0 ÷ 255

int System.Int32 short 16 -32768 ÷ 32767

ushort 16 0 ÷ 65535
long System.Int64
int 32 -2147483648 ÷ 2147483647
byte System.Byte
uint 32 0 ÷ 4294967295
ushort System.UInt16
-9223372036854775808 ÷
long 64
9223372036854775807
uint System.UInt32
ulong 64 0 ÷ 18446744073709551615
ulong System.UInt64

20
Tipurile reale:
• corespund celor din C/C++ şi se bazează pe
formatul flotant IEEE 754

Tip C# Tip System Nr. Domeniu de


Tip Precizie
biţi valori
float System.Single
1.5 x 10-45 ÷ 3.4 x
float 32 7 cifre
double System.Double 1038

decimal System.Decimal 5.0 x 10-324 ÷ 1.7 x


double 64 15-16 cifre
10308
28-29 poziţii 1.0 x 10-28 ÷ 7.9 x
decimal 128
zecimale 1028

• valori particulare:
• +0, -0, +00, -00, NaN (Not a Number)
21
Tipurile reale

• Literalii flotanţi pot fi utilizaţi pentru iniţializarea


tipurilor reale, atât în forma zecimală cât şi în
cea exponenţială

• Tipul decimal:
– se reprezintă pe 16 octeţi şi permite reprezentarea
unor valori cu până la 28 de cifre semnificative,
precum şi a punctului zecimal
– are un domeniu de valori mai mic dar o precizie mai
bună, motiv pentru care se foloseşte pentru calcule
financiare
– nu admite valorile particulare de la celelalte tipuri

22
• Tipul caracter (char)(System.Char):
– reprezintă un caracter Unicode

• Tipul boolean (bool)(System.Boolean):


– reprezintă o valoare logică, căreia i se pot atribui doar
literalii true sau false
– nu sunt admise nici un fel de conversii de la acest tip
către un alt tip

• Tipul string (System.String):


– reprezintă o secvenţă de caractere Unicode
– datorită utilizării intense sunt permise construcţii de
forma:
• string s = “abcd”; deşi string este o clasă 23
– şirurile nu mai pot fi modificate (imutable)
– pot fi concatenate cu operatorul ‘+’
– elementele din şir pot fi referite cu operatorul de
indexare ‘[ ]’
– deşi sunt tipuri referinţă, valorile şirurilor pot fi
comparate cu operatorii ‘==’ şi ‘!=’
– clasa String oferă multe facilităţi utile pentru şiruri:
• Length Lungimea şirului de caractere
• Concat( ) Metodă statică prin care se obţine un şir nou, format
din două sau mai multe şiruri
• CompareTo( ) Metodă de comparare a şirului dat cu un alt şir de
caractere
• Format( ) Permite formatarea datelor
• SubString( ) Metodă de găsire a unui subşir într-un şir dat
• IndexOf( ) Dă poziţia de la care începe un caracter sau şir într-
un alt şir
• Insert( ) Returnează un şir nou, ce conţine inserat şirul 24
specificat
• Tipul obiect (object)(System.Object):
– stă la baza tipurilor valoare cât şi a tipurilor referinţă
– sistem unificat de tipuri (“unified type system”)
– este posibil apelul unor metode şi pentru tipul valoare:

int i=10;
Console.Write(i.ToString( ));

– o variabilă de tip valoare poate fi convertită către tipul


Object prin operaţia numită “boxing”, operaţie prin
care se alocă un obiect “box” în care se copiază
valoarea variabilei

25
– operaţia inversă se numeşte “unboxing” şi implică
copierea unei valori dintr-un obiect box într-o locaţie
de memorie:

int i=23;
object ob = i; // boxing
int k = (int)ob; // unboxing

– această posibilitate de a trata tipurile valoare ca şi


obiecte face legătura între tipul valoare şi tipul
referinţă
• în majoritatea limbajelor de programare, aceste tipuri sunt
tratate complet separat.

26
• Tipul DateTime:
– permite reprezentarea:
• datei (an, luna, zi)
• şi/sau timpului (secunde scurse de la ora 0 a zilei respective)

– o variabilă de acest tip este iniţializată implicit cu data


01/01/0001 şi ora 0:00 AM

27
Variabile
• Fiecare variabilă are asociat un tip care
defineşte domeniul de valori pentru variabilă şi
operaţiile posibile asupra acesteia
• O variabilă poate fi una locală, un parametru
formal al unei metode, un element de tablou, un
câmp instanţă sau un câmp static

• In limbajul C# nu există declaraţii globale


pentru variabile sau funcţii !
– comportamentul funcţiilor sau variabilelor globale
poate fi obţinut cu ajutorul metodelor statice respectiv
variabilelor statice
28
Variabile

• O variabilă locală este declarată în metode,


proprietăţi sau indexatori printr-o declaraţie:
tip variabila [= expresie];
const tip variabila = expresie_constanta;

• Domeniul unei variabile se întinde din locul


declaraţiei până la sfârşitul blocului în care
apare declaraţia

• In blocul curent sau în alte blocuri imbricate


nu mai pot fi declarate alte variabile cu
acelaşi nume

29
Variabile

• Variabilele introduse cu modificatorul const


trebuie obligatoriu iniţializate la declarare, iar
orice tentative de a atribui valori acestor
variabile sunt considerate erori

• Compilatorul evaluează aceste variabile în etapa


de compilare şi ca urmare se pot face optimizări
suplimentare dacă se folosesc constante definite
anterior:
const double PI = 3.1415926;
const double PI2 = 2*PI;

30
Variabile

• Limbajul C# este puternic tipizat:


– operaţiile posibile asupra unei variabile sunt forţate în
etapa de compilare şi nu la execuţie

• C# este un limbaj sigur din punctul de vedere al


tipului (type-safe):
– asigură, prin verificări de tip în timpul execuţiei, că
operaţiile asupra unei variabile se fac numai prin tipul
adecvat de date

31
Variabile

• O variabilă trebuie iniţializată înainte de utilizare


– acest lucru se poate face prin atribuiri explicite

– dar există şi iniţializări implicite pentru câmpuri


instanţe, câmpuri statice sau elemente de tablou:

Tip Valoare implicită


Numeric 0
Bool false
Char ‘\0’
Enum 0
Reference null

32
Tablouri
• Un tablou este o listă de elemente de acelaşi tip

• Tipul elementelor tabloului reprezintă tipul


tabloului respectiv

• Orice tablou are un nume

• Ca şi tipuri, tablourile sunt derivate din clasa


System.Array şi se declară cu ajutorul
operatorului de indexare ([ ])
33
Tablouri unidimensionale
• Elementele unui astfel de tablou sunt plasate
succesiv într-o zonă contiguă de memorie

• Un tablou unidimensional se declară astfel:


Tip [ ] nume_tablou = new Tip [dimensiune]
[={expresii_de_initializare}];

– Tip este un tip predefinit sau definit de utilizator


– nume_tablou este un identificator C#
– dimensiune este o expresie întreagă şi pozitivă ce
specifică numărul de elemente din tablou
34
Tablouri unidimensionale

• Pentru referirea unui element se foloseşte


operatorul de indexare [ ], precizând numele
tabloului şi poziţia elementului în tablou (indexul
sau indicele):
nume_tablou[index];

– indexul este, în general, o expresie întreagă şi


pozitivă
– primul element are indexul 0, iar ultimul are indexul
(dimensiune-1)

• Dimensiunea zonei de memorie care se alocă


tabloului:
dimens_memorie = sizeof(tip) * dimensiune
35
Tablouri unidimensionale

• Exemplu:
int [ ] tab = new int[10];  int [ ] tab; tab = new int [10];
tab[0] = 1;
tab[9] = 11;

• Pentru tablouri locale sau tablouri câmpuri, este


admisă o formă prescurtată a declaraţiei de forma:
int [ ] tab = {1,2,3}; <=> int [ ] tab = new int [ ] {1,2,3};

• Pentru un tablou creat nu se mai poate modifica


dimensiunea acestuia
• Există în schimb clasa System.Collection ce
implementează tablouri cu dimensiune variabilă
36
Tablouri multidimensionale
• Tipuri de tablouri multidimensionale:
– regulate
– neregulate (jagged) sau imbricate

• Tablourile regulate:
– reprezintă blocuri compacte cu mai multe dimensiuni,
numărul acestora fiind fix şi precizat în momentul
declarării:
float [, ,] cub = new float [3, 5, 7]; // un singur tablou

cub[1,1,1] = 10.10;
– fiecare vector care intră în componenţa tabloului are o
dimensiune fixă şi ca urmare, tabloul va avea o
dimensiune fixă de 3*5*7 elemente de tipul întreg
– aceste tipuri de tablouri sunt similare celor din C/C++
37
Tablouri multidimensionale

• Tablourile regulate ocupă zone contigue în memoria


RAM a calculatorului

38
Tablouri multidimensionale

• Tablouri neregulate (jagged):


– se referă la tablouri de tablouri (elementele tabloului
sunt la rândul lor tablouri):
int [ ][ ] matrice = new int [4][ ];
for(int i=0; i<3; i++) {
matrice[i] = new int[5];
}
matrice[0][1] = 0;
matrice[1][1] = 5;

– prima parte a declaraţiei introduce tipul elementelor


tabloului şi forma acestuia, pe când a doua parte
constituie expresia de creare şi precizează
dimensiunea tabloului
– în acest caz, fiecare vector ce formează tabloul poate
avea orice dimensiune
39
Tablouri multidimensionale

– fiecare pereche de paranteze pătrate poate fi folosită


pentru a specifica un alt tablou (uni sau
multidimensional):
long[2][5] Distante;
long[2,4][5] Distante;
long[2,4][5,12,8] Distante;

– prima dimensiune poate lipsi când se face iniţializarea


la declarare:
string[ ][ ] Membri = new string[2][ ]{
new string[ ]{"SM1", "SM2", "SM3"},
new string[ ]{"SS1", "SS2", "SS3", "SS4"}
};

40
Tablouri multidimensionale

– în cazul acestui tip de tablouri, alocarea memoriei


poate lua forme diverse
– astfel putem avea mai multe linii ce pointează către
acelaşi vector, linii nealocate sau referinţe încrucişate

41
Clasa System.Array
• De fiecare dată când se crează un tablou se crează o nouă
clasă derivată din clasa Array definită în spaţiul de nume
System
• Ca urmare se moştenesc diverse proprietăţi şi metode, ce
pot fi utilizate cu noul tablou, cum ar fi:
– SetValue(valoare, index);
– GetValue(index);
– Nume_tablou.Length; // numărul de elemente
– Nume_tablou.Rank; // numărul de dimensiuni ale unui tablou
– GetLowerBound(int); // limita inferioară pe o dimensiune
– GetUpperBound(int); // limita superioară pe o dimensiune
– GetLength(int); // numărul de elemente pe o dimensiune
– Sort( ); // sortează elementele unui tablou unidim.
– Reverse( ); // permite inversarea ordinii într-un tablou
• Tablourile definite ca instanţe ale clasei System.Array au
dezavantajul că au dimensunea fixă (odată declarată la
creare, această dimensiune nu mai poate fi modificată) 42
Clasa System.Array

• Limbalul C# (prin intermediul CLR) asigură


verificări de domeniu de indici în timpul execuţiei
unui program şi generează excepţia de tipul
IndexOutOfRangeException pentru indecşi
invalizi

• Tablourile au tipul referinţă, astfel că declaraţia


unui tablou doar rezervă spaţiu pentru adresa
către acel tablou şi nu rezervă spaţiu pentru
elementele tabloului

• Elementele tabloului sunt efectiv create în urma


alocării dinamice cu specificarea dimensiunii sau
cu iniţializări
43
Enumerări
• Enumerările introduc un grup de constante cu
nume
• Sintaxa declaraţiei unei enumerări este
următoarea:
enum nume_enumerare [: tip_intreg]
{membri_enumerare [ = valoare]};

• Dacă nu se specifică altceva, enumerările sunt


de tip întreg şi membri acestora primesc valori
constante întregi începând cu valoarea 0,
continuând cu 1,2,…
• Valoarea unui membru se determină prin
incrementarea valorii membrului precedent,
dacă nu apare o iniţializare explicită
44
Enumerări

• Exemplu:
enum Culori : byte{Red, Green=2, Blue};

• Membri unei enumerări se folosesc împreună cu


numele enumerării:
Culori clr = Culori.Red;

• Tipul enum este derivat din clasa System.Enum


ce are mai multe metode statice care permit:
– determinarea tipului unei enumerări
– verificarea dacă o anumită valoare este admisă
– iniţializarea unei enumerări pornind de la un şir
constant
– obţinerea listei de valori din enumerare
– conversii, etc. 45
Enumerări

• Enumerările suportă anumiţi operatori:


– relaţionali: ==, !=, <, >, <=, >=
– aritmetici: +, -, ++, --
– logici pe biţi: &, |, ^, ~
– sizeof

• Compilatorul nu verifică dacă rezultatul este o


valoare validă din enumerare
• Se pot face conversii explicite de forma:
– enum <-> enum
– tip întreg <-> enum

• Numai literalul numeric 0 este convertit implicit


în tipul enum
46
Instrucţiuni
• Majoritatea instrucţiunilor din limbajul C# sunt
preluate din limbajele C/C++

• Unele instrucţiuni sunt modificate altele sunt noi

• Instrucţiunea expresie:
[variabila =] expresie;

– caz particular, instrucţiunea vidă: ;


– un alt caz particular îl constituie expresiile booleene:
• instrucţiunile de decizie şi cele ciclice folosesc expresii
booleene spre deosebire de limbajul C++ ce foloseşte
expresii ce sunt evaluate la o valoare întreagă

47
Instrucţiuni

• Instrucţiuni de selecţie
– Instrucţiunea if-else
if(expresie_booleană)
instrucţiune
[else
instrucţiune]

– Instrucţiunea switch
switch(expresie_switch)
{
[case expresie_const:
instrucţiune]
[default :
instrucţiune]
}
48
Instrucţiuni

– Instrucţiunea switch poate evalua numai expresii ce


au un tip predefinit (tipuri întregi, caracter sau şir) sau
tipul enum (C++ nu permite tipul enum)

– După execuţia unei instrucţiuni asociate unei etichete


case nu se termină execuţia instrucţiunii switch

– Ca urmare trebuie controlat fluxul execuţiei prin


instrucţiuni de salt (break sau goto)

49
Instrucţiuni

• Instrucţiuni de ciclare
– Instrucţiunea while
while(expresie booleană)
instrucţiune

– Instrucţiunea do-while
do
instrucţiune
while(expresie booleană);

– Instrucţiunea for
for([expresie_iniţializare]; [expresie_booleană]; [expresie_iterare])
instrucţiune

50
Instrucţiuni

– De obicei, instrucţiunea for se foloseşte atunci când


se doreşte controlul valorii unui iterator (variabilă de
ciclare)

– Prima instrucţiune, de regulă, iniţializează variabila


iterator, pe când ultima instrucţiune modifică această
variabilă (de obicei prin incrementare sau
decrementare)

51
Instrucţiuni

• Instrucţiunea foreach
foreach(tip_valoare in IEnumerable)
instrucţiune

– se foloseşte pentru colecţii (inclusiv tablouri)


– se execută instrucţiunea asociată pentru fiecare
element din colecţie
– elementele extrase din colecţie nu pot fi însă
modificate
– toate colecţiile încurajează acest tip de funcţionalitate
prin implementarea tipului IEnumerable şi
IEnumerator

52
Instrucţiuni

using System;

class ForEachLoop
{
public static void Main()
{
string[ ] names = {“Iuan", “Ghio", “Vasai", “Ghiran"};

foreach (string person in names)


{
Console.WriteLine("{0}", person);
}
}
}

53
Instrucţiuni

• Spaţiul de nume System.Collections conţine mai multe


clase care servesc ca şi containere pentru colecţii de
date:
ArrayList Tablou redimensionabil
BitArray Tablou de biţi
Hashtable Tablou de perechi cheie/valoare
Queue Coada (FIFO)
SortedList Tablou de perechi cheie/valoare ordonate
Stack Stiva (LIFO)

• Tablourile de tipul ArrayList se pot folosi atunci când


dimensiunea tablourilor nu se cunoaşte în momentul
compilării (ci va fi stabilită ulterior, la execuţie sau la
runtime), sau este necesară redimensionarea acestora

54
Instrucţiuni

• Clasa ArrayList pune la dispoziţie mai multe metode şi


proprietăţi utile pentru manevrarea unor astfel de colecţii
de date:
– Count Proprietate care returnează numărul de elemente
existente în tablou
– Capacity Proprietate pentru citirea şi setarea numărului de
elemente pe care îl poate conţine tabloul
– Add( ) Metodă publică de adăugare a unui element în tablou
– Insert( ) Metodă publică de inserare a unui element în tablou
– Sort( ) Metodă publică de sortare a elementelor unui tablou

55
Instrucţiuni

• Instrucţiuni de salt
– Asigură transferul controlului execuţiei programului în
altă parte
– Există restricţii în utilizarea acestor instrucţiuni în
interiorul unui bloc try-finally

– Instrucţiunea break: break;


• Asigură ieşirea necondiţionată dintr-o instrucţiune ciclică sau
din instrucţiunea switch ce conţine instrucţiunea break

– Instrucţiunea continue: continue;


• Asigură saltul peste instrucţiunile următoare ale unei ciclu
(while, do-while, for, foreach) şi forţează începutul unei noi
iteraţii

56
Instrucţiuni

– Instrucţiunea goto:
goto instrucţiune_cu_eticheta;
goto eticheta_case;
• In prima variantă, această instrucţiune se foloseşte de obicei
pentru a transfera controlul în afara unui ciclu imbricat (din
interior spre exterior), dar nu se poate folosi pentru transferul
execuţiei în interiorul unui ciclu imbricat
– Instrucţiunea return: return [expresie];
• Determină ieşirea dintr-o metodă (funcţie)
• Dacă metoda returnează ceva este obligatorie prezenţa
expresiei, având tipul specificat în metodă.
– Instrucţiunea throw: throw expresie_excepţie;
• Instrucţiunea activează o excepţie pentru a indica o situaţie
anormală apărută în timpul execuţiei programului

57
Instrucţiuni

• Instrucţiunea lock: lock (expresie)


instrucţiune
– Permite obţinerea unei excluziuni mutuale pentru un
anumit obiect, execută instrucţiunea asociată şi apoi
eliberează excluziunea
– Această instrucţiune este o altă formă prin care se
permite apelul metodelor Enter( ) şi Exit( ) din clasa
Monitor

• Instrucţiunea using: using (expresie_declaraţie)


instrucţiune
– Permite obţinerea unor resurse, execuţia unei
instrucţiuni şi apoi eliberarea resurselor
– O resursă poate fi o clasă sau structură ce
implementează tipul System.IDisposable, tip ce
permite apelul metodei Dispose( ) pentru eliberarea
unei resurse 58
Instrucţiuni

– Utilizarea acestei instrucţiuni este echivalentă cu


utilizarea unui bloc try-finally:
using (R r1 = new R()) {
// cod
}

R r1 = new R();
try {
// cod
}
finally {
if (r1 != null)
(IDisposable)r1.Dispose();
}
59
Directive preprocesor
• In limbajul C#, se utilizează termenul de
“directive preprocesor” pentru compatibilitatea
cu limbajele C/C++

• In C# nu există preprocesare ca etapă separată


în procesul de pregătire a unui program

• Directivele sunt prelucrate în faza de analiză


lexicală din cadrul compilării

• Directivele preprocesor încep întotdeauna cu


caracterul #
60
Directive preprocesor

• Facilităţi:
– definirea unor constante simbolice folosite la
compilarea condiţionată: #define, #undef
– compilarea condiţionată: #if, #elif, #else, #endif
– controlul numărului de linie în procesul de compilare
pentru afişarea erorilor şi avertismentelor: #line
– generarea unor mesaje de eroare sau avertizare:
#error, #warning
– marcarea explicită a unor zone din codul sursă:
#region, #endregion

• Se observă lipsa directivei preprocesor C++


include. In C# nu există fişiere antet !
– aceasta este înlocuită de directiva using

61
Directiva using

• Directiva using se utilizează în două scopuri:


– să permită folosirea unor tipuri din spaţii de nume fără calificare
completă
– pentru a crea un alias pentru un spaţiu de nume
• In prima situaţie, forma este următoarea:
using namespace;
• In a doua situaţie, se foloseşte forma:
using alias = type|namespace;
– unde alias este un identificator (nume utilizator) ce se va folosi
ulterior pentru a reprezenta un tip sau un spaţiu de nume

62
Directiva using

• Există câteva caracteristici ale directivei using


de care trebuie să se ţină seama:
– domeniul unei astfel de directive este fişierul în care
apare directiva
– un alias se crează pentru a califica mai uşor un spaţiu
de nume sau un tip existent
– atunci când se utilizează o directivă using pentru a
folosi tipuri dintr-un spaţiu de nume, trebuie ştiut că
aceasta nu dă acces la alte spaţii de nume incluse în
primul spaţiu de nume

63

S-ar putea să vă placă și