Documente Academic
Documente Profesional
Documente Cultură
Scurt istoric
C# (pronunai C sharp - in traducere literal C diez) este un limbaj de
programare orientat pe obiecte asemntor limbajului C++. El a fost dezvoltat de firma
Microsoft, ca soluie standard pentru dezvoltarea aplicaiilor Windows. Creatorii lui sunt
Anders Hejlsberg (autor al limbajelor Turbo Pascal i Delphi), Scot Wiltamuth i Peter
Golde.
C#
respect
standardul
ECMA-334
(European
Computer
Manufactures
Association).
Limbajul C# folosete Microsoft .NET Framework, o colecie de clase care poate
fi descrcat prin Internet i care este ntreinut i ameliorat permanent de Microsoft.
Prima versiune dateaz din 2001, deci toat aceast soluie tehnologic este de dat
recent.
Clasele coninute n .NET sunt neutre fa de limbaj (aplicaiile pot fi scrise n
diverse limbaje) i uureaz munca de programare n realizarea interfeelor aplicaiilor,
accesul la date, conectarea la servere de baze de date, accesarea resurselor din
Internet, programarea aplicaiilor bazate pe comunicaii prin reele, etc..
Aplicaiile care folosesc .NET sunt executate ntr-un mediu software denumit
CLR (Common Language Runtime).
aceast form aplicaia este apoi trimis procesorului virtual (CLR) care realizeaz
traducerea n cod main i execut aplicaia.
Compilare
Limbaj intermediar
(Common Intermediate
Language - CIL)
fi
versiunea
Express
Edition
mediului
profesional
realizrii aplicaiilor folosind pachetul gratuit .NET Framework Software Development Kit
(SDK).
(xx este versiunea descrcat) compilatorul csc.exe utilizabil n mod linie de comand i
care produce cod executabil.
Exemplu de aplicaie tip consol:
class Salut
{
public static void Main()
{
System.Console.WriteLine("Salut, prieteni!");
}
}
Observaie:
Pentru a folosi compilatorul csc.exe fr a preciza calea este necesar
modificarea variabilei de mediu Path. Pentru aceasta se va accesa Control Panel /
System / Advanced. n fereastra care se afieaz se va selecta Environment Variables
iar n fereastra Environment Variables va fi editat variabila Path adugnd cilor deja
existente calea spre directorul care conine compilatorul csc.exe.
Pentru .NET
versiunea 3.5, cea mai recent n momentul scrierii acestui curs, calea este:
C:\WINDOWS\Microsoft.NET\Framework\v3.5.
Noiuni de C#
Spaii de nume
Spaiul de nume reprezint un concept aprut n C++ odat cu extinderea
programrii obiectuale. Clasele care alctuiesc o aplicaie pot proveni din surse diferite
i pot avea din ntmplare aceeai denumire. Dac programatorii au creat clasele n
spaii de nume distincte, eventualele coincidene de nume pot fi uor rezovate,
denumirea fiecrei clase fiind precedat de denumirea spaiului de nume cruia i
aparine.
Pentru a evita tastarea spaiului de nume naintea fiecrei denumiri de clas n
C# se folosete ca i n C++ clauza using.
.NET Framework definete peste 90 de spaii de nume, majoritatea avnd
denumiri ncepnd cu System. n exemplele coninute n cursurile urmtoare vor fi
frecvent folosite spaiile de nume System, System.Windows.Form i System.Drawing.
Exemplul de aplicaie prezentat poate fi rescris folosind clauza using, clasa
Console aparinnd spaiului de nume System.
using System;
class Salut
{
public static void Main()
{
Console.WriteLine("Salut, prieteni!");
}
}
Comentarii
Programele scrise n C# pot conine explicaii sub forma unor comentarii.
Acestea vor asigura n timp nelegerea diferitelor metode i rolul funcional al
variabilelor folosite.
Ca i n C++, n n C# pot fi folosite dou tipuri de comentarii:
comentarii "n linie", introduse prin //. Un astfel de comentariu se ncheie la
sfritul liniei curente;
comentarii pe unul sau mai multe rnduri consecutive. Zona care conine
comentariul este delimitat prin /*
(comentariu) */.
De regul se folosesc comentariile n linie, cel de-al doilea tip fiind folosit frecvent
n timpul depanrii programelor mari i complexe, pentru a suprima din program
anumite zone.
Tipuri de date
n mare C# folosete tipurile de date simple existente i n C++. Fiecare dintre
tipurile simple este ns dublat de o clas din spaiul de nume System. Rolul acelei
clase este puin evident n acest moment. n cele ce urmeaz va fi inclus un exemplu n
care vor fi referite proprieti ale tipurilor simple n acelai mod n care sunt referite
proprieti ale claselor. De exemplu int.MaxValue, furnizeaz valoarea ntreag cea mai
mare care poate fi pstrat ntr-o variabil de tip int. Tot dublarea tipurilor simple prin
clase va face posibil folosirea unor variabile aparinnd unor tipuri simple n situaii n
care sunt acceptate doar obiecte.
Tip simplu
Clas
Semn
sbyte
System.SByte
cu semn
byte
System.Byte
fr semn
16
short
System.Int16
cu semn
16
ushort
System.UInt16
fr semn
32
int
System.Int32
cu semn
32
uint
System.UInt32
fr semn
64
long
System.Int64
cu semn
64
ulong
System.UInt64
fr semn
Exemple de declaraii:
int a = 12, b, contor; // Se putea scrie i System.Int32 a = 12, b, contor;
b. Tipuri de date reprezentate n virgul mobil
Numr de bii
Tip simplu
Clas
32
float
System.Single
64
double
System.Double
c. Tipul decimal
Limbajul C# admite pe lng tipurile de date numerice menionate un tip nou,
decimal.
Tipul char permite declararea unei variabile care va conine un caracter n format
Unicode (pe 16 poziii binare). Clasa corespunztoare din spaiul de nume System este
System.Char.
f. tipul string
O simplificare semnificativ pe care o aduce C# n raport cu C++ este
introducerea tipului string pentru declararea variabilelor care conin iruri de caractere.
Clasa corespunztoare din spaiul de nume System este System.String.
Exemple:
string a = "X = "; // Se putea i System.String a = "X = ";
double p = 129.2;
int nr = a.Length; // .Length furnizeaz lungimea irului a.
string b = a + p + "mm";
n C# operatorul '+' indic fie operaia de adunare fie cea de concatenare (unire)
a dou iruri de caractere. Pentru toate tipurile de date menionate (mai exact pentru
toate tipurile derivate din clasa Object, rdcina ierarhiei de clase destinate pstrrii
datelor) este definit metoda ToString() care returneaz o reprezentare sub form de ir
de caractere a valorii variabilei pentru care este apelat.
Dup declarare valoarea variabilei tab este null. Variabila va primi o valoare
diferit de null n momentul rezervrii unei zone de memorie pentru pstrarea
elementelor tabloului, folosind operatorul new:
tab = new int[12];
Ulterior se poate folosi variabila tab pentru un alt ir de valori int, astfel:
tab = new int[5];
disponibile face obiectul activitii unei componente a CLR denumit garbage collector
(colector de reziduuri).
Exemplu: S se scrie o aplicaie tip consol care afieaz valorile numerice
maxime i minime care pot fi memorate folosind diferite tipuri de variabile.
using System;
class Dimens
{
public static void Main()
{
Console.WriteLine("Sbyte: {0} la {1}",sbyte.MinValue, sbyte.MaxValue);
Console.WriteLine("byte: {0} la {1}",byte.MinValue, byte.MaxValue);
Console.WriteLine("Short: {0} la {1}",short.MinValue, short.MaxValue);
Console.WriteLine("uShort: {0} la {1}",ushort.MinValue, ushort.MaxValue);
Console.WriteLine("int: {0} la {1}",int.MinValue, int.MaxValue);
Console.WriteLine("uint: {0} la {1}",uint.MinValue, uint.MaxValue);
Console.WriteLine("long: {0} la {1}",long.MinValue, long.MaxValue);
Console.WriteLine("ulong: {0} la {1}",ulong.MinValue, ulong.MaxValue);
Console.WriteLine("float: {0} la {1}",float.MinValue, float.MaxValue);
Console.WriteLine("double: {0} la {1}",double.MinValue, double.MaxValue);
}
}
Operatorii limbajului C#
n definirea unui limbaj, stabilirea operatorilor care pot fi folosii la scrierea
expresiilor i a regulilor lor de utilizare reprezint o etap important. Limbajele de nivel
nalt folosesc un mare numr de operatori i chiar permit extinderea setului de operatori
pentru a putea scrie expresii n care intervin variabile aparinnd tipurilor structurate
(obiecte).
Operatorii matematici din C#
+
% (modulo)
i < (lim + 1)
Operatorii de incrementare i de decrementare ++ i -n funcie de poziia operatorului fa de variabila incrementat, se realizeaz pre
i post incrementare (decrementare)
int n = 5 ;
x = n++ ;
atribuie 5 lui x
x = ++n ;
atribuie 6 lui x
n care variabila din stnga egalului se repet n dreapta acestuia se mai poate scrie
astfel :
i += 3 ;
Instruciunile limbajului C#
Instruciunea de decidere - if
Ca i n C, ansamblul de instruciuni cuprinse ntre acolade formeaz o
instruciune compus sau un bloc de instruciuni. Instruciunile din interiorul unui bloc
de instruciuni sunt executate n ordinea n care sunt scrise.
Variante de scriere a instruciunii if
if ( expLogica )
instruciune;
if (expLogica )
{
mai multe instruciuni
}
if (expLogica )
instruciune;
else
instruciune;
if (expLogica )
{
mai multe instruciuni
}
else
{
mai multe instruciuni
}
if (expLogica )
instruciune;
else
{
mai multe instruciuni
}
if (expLogica )
{
mai multe instruciuni
}
else
instruciune;
Instruciunea while
Instruciunea while permite realizarea unei structuri repetitive (ciclu) condiionate
anterior. Corpul ciclului poate fi executat o dat, de mai multe ori sau de loc.
Exemplu fundamental:
int contor = 1;
while ( contor <= 3 )
{
Console.WriteLine("Contor = "+contor);
contor = contor + 1; // sau mai bine contor++
}
Console.WriteLine("La revedere!");
while ( condiie )
{
una sau m. m.instruciuni
}
Instruciunea do
poate primi valori dect n interiorul ciclului, programatorul trebuie s-i dea la nceput o
valoare convenabil pentru a determina intrarea n ciclu. Exacutarea instruciunilor din
corpul ciclului va corecta automat valoarea iniial.
Pentru astfel de cazuri exist ns i o cale mai simpl, respectiv folosirea
instruciunii do.
Exemplu:
g = 9.81;
t = 0;
do
{
d = (g * t * t ) / 2;
Console.WriteLine( t + " " + d);
t = t + 1;
}
while (d <= 500);
Instruciunea for
Instruciunea for este preferat ori de cte ori trebuie realizat un ciclu care
folosete un contor.
Dac naintea unui ciclu trebuie realizate mai multe iniializri, acestea pot scrise
n for una dup alta, desprite prin virgule:
class Program
{
public static void Main(String[] args)
{
int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int i, sum;
for (i = 0, sum = 0; i < a.Length; i++)
sum = sum + a[i];
Console.WriteLine("Suma elementelor sirului a este: " + sum);
}
}
Oricare dintre cele trei pri ale instruciunii for pot lipsi. Lipsa condiiei de reluare
este echivalent cu a scrie o condiie care este ntotdeauna adevrat. Ieirea dintr-un
astfel de ciclu se poate face folosind instruciunea break.
Exemplu:
for ( ; ; )
{
..
break;
..
}
Executarea instruciunii break provoac o ieire imediat din ciclul for. Ea poate
fi folosit i pentru a iei din ciclurile while sau do.
Instruciunea foreach
Instruciunea foreach a fost preluat n C# din Visual Basic.
Ea permite
n exemplu, primul foreach pune 10 n toate elementele din irul de valori ir iar al
doilea afieaz valorile sdin ir pe o linie.
Instruciunea switch
Instruciunile de ciclare prezentate, sunt folosite pentru realizarea blocurilor de
instruciuni a cror execuie ncepe cu prima linie i este controlat de ctre
programator.
instruciuni dar punctul de unde ncepe execuia depinde de valoarea unei expresii
avnd valori ntregi.
Sintaxa instruciunii este:
switch (expresie)
{
case constanta_1 : instruciuni
case constanta_2 : instruciuni
...
default : instruciuni;
}
Fiecare dintre punctele de unde poate ncepe execuia blocului este etichetat
printr-o constant avnd valoare ntreag. Dac expresia de testat corespunde uneia
dintre constante, execuia blocului ncepe din punctul indicat de aceasta.
Cazul default este facultativ.
Exemplu :
switch (t)
{
case 's':
rez = Math.Sin(Math.PI * x / 180.0);
Console.WriteLine("rezultatul este : " + rez);
break;
case 'c':
rez = Math.Cos(Math.PI * x / 180.0);
Console.WriteLine("rezultatul este : " + rez);
break;
case 't':
rez = Math.Sin(Math.PI * x / 180.0) / Math.Cos(3.14159 * x / 180.0);
Console.WriteLine("rezultatul este : " + rez);
break;
default:
Console.WriteLine("Caracter incorect!");
break;
}
Programare obiectual n C#
Limbajul C# permite scrierea de aplicaii folosind exclusiv programarea
obiectual. O aplicaie scris n C# este alctuit dintr-un ansamblu de clase, una
dintre ele fiind clasa principal deoarece conine metoda Main(), punctul de intrare n
aplicaie.
Exemplu fundamental:
numete constructor;
AnBisect(), care returneaz o valoare bool care indic dac anul este an
bisect i
ZiuaDinAn() care calculeaz a cta zi din an este ziua definit prin valorile
curente din cmpurile clasei.
{
class Program
{
public static void Main(String[] args)
{
DCalend data = new DCalend(2007, 8, 29);
Console.WriteLine("Ziua din an = {0}", data.ZiuaDinAn());
}
}
class DCalend
{
private int anul;
private int luna;
private int ziua;
public DCalend(int aa, int ll, int zz)
{
anul = aa;
luna = ll;
ziua = zz;
}
public bool AnBisect()
{
return (anul % 4 == 0) && ((anul % 100 != 0) || (anul % 400 ==
0));
}
public int ZiuaDinAn()
{
int[] luniz = new int[] { 0,31, 59, 90, 120, 151,
181, 212, 243, 273, 304, 334};
return luniz[luna - 1] + ziua + (luna > 2 && AnBisect() ? 1 : 0);
}
}
}
Pe lng clasa DCalend aplicaia mai are clasa Program care conine doar
metoda principal Main(). n metoda principal se declar i se iniializeaz (prin apelul
constructorilui) obiectul data i apoi se afieaz pe ecran a cta zi din an este data.
Pentru apelul metodelor clasei DCalend se scrie:
AnBisect() dac metoda este apelat dintr-o alt metod a aceleiai clase.
pentru apelul ei nefiind necesar definirea n prealabil a unui obiect aparinnd aceleiai
Proprieti
Ca i n orice alt limbaj care permite programarea obiectual, n C# o clas are
membri date denumii i cmpuri i membrii coninnd cod denumii metode. Clasele
C# mai pot conine i ali membrii coninnd cod denumii proprieti, extrem de
importani n .NET Framework.
Originea problemei rezolvate prin introducerea proprietilor este urmtoarea:
metod
pentru
modificarea
valorii,
denumit
de
obicei
setnume_camp(tip val_noua) i
De altfel programatorii n C#
Parametrii metodelor
n C# parametrii metodelor sunt ntodeauna transferai prin valoare. Ca i n C,
n acest caz modificrile operate n cadrul metodei asupra valorilor parametrilor formali
ai acesteia nu schimb valorile variabilelor corespunztoare din metoda apelant.
Exemplu:
using System;
namespace Test
{
class Invers
{
public static void Main(string[] args)
{
Invers z = new Invers();
z.Calcule();
}
public void Calcule()
{
int a=10, b=2;
Console.WriteLine("Valori initiale: a = {0}, b = {1}", a, b);
Inv(a, b);
Console.WriteLine("Dupa apel: a = {0}, b = {1}", a, b);
}
public void Inv(int x, int y)
{
int aux;
aux = x;
x = y;
y = aux;
}
}
}
Metoda Inv() din exemplul dat este eronat deoarece transmiterea prin valoare a
parametrilor face ca inversarea realizat s nu afecteze variabilele din metoda apelant
(a i b).
Motenirea
Toate limbajele destinate programrii obiectuale permit realizarea unor clase
derivate din clase existente.
proprietile clasei de baz. n cadrul ei se pot ns aduga noi membri, date sau
metode, prin care se realizeaz practic un proces de specializare a noii clase.
La definirea unei clase derivate programatorul poate de asemenea nlocui unele
dintre metodele clasei de baz cu metode noi, mai bine adaptate.
Redefinirea
metodelor clasei de baz se mai numete i suprascriere, noile metode avnd evident
aceeai declaraie cu cele din clasa de baz.
Exemplu:
using System;
namespace TestOvr
{
class Program
{
static void Main(string[] args)
{
Derivata obj = new Derivata();
obj.Autentifica_te();
}
}
public class ClasaDeBaza
{
public void Autentifica_te()
{
Console.WriteLine("Clasa de baza");
}
}
public class Derivata : ClasaDeBaza
{
public void Autentifica_te()
{
Console.WriteLine("Clasa derivata");
}
}
}
Noua clas, Derivata a fost declarat folosind sintaxa public class Derivata :
ClasaDeBaza astfel indicndu-se relaia de derivare. n C# o clas poate avea o singur
Rezultat:
b. Modul new
using System;
namespace TestOvr
{
class Program
{
static void Main(string[] args)
{
ClasaDeBaza obj = new Derivata();
obj.Autentifica_te();
}
}
public class ClasaDeBaza
{
public virtual void Autentifica_te()
{
Console.WriteLine("Clasa de baza");
}
}
public class Derivata : ClasaDeBaza
{
public new void Autentifica_te()
{
Console.WriteLine("Clasa derivata");
}
}
}
Rezultat:
Tratarea excepiilor
n timpul exectrii unui program pot aprea situaii n care o eroare (denumit i
excepie program) produs ntr-un modul al programului face imposibil continuarea
acestuia. Dac uneori se pot include secvene de validare a datelor pentru ca situaiile
de eroare s fie evitate, n alte cazuri acest lucru nu este posibil sau ar complica mult
scrierea programului. O modalitate elegant de rezolvare a situaiilor care pot aprea o
O secven de cod poate declana uneori mai multe tipuri excepii. C# permite n
aceste cazuri interceptarea separat a fiecruia dintre tipurile care ar putea aprea,
dup modelul:
try
{
. . . (secventa de cod generatoare de erori)
}
catch (NullReferenceException ex)
{
. . . (tratare excepie 1)
}
catch (ArgumentOutOfRangeException ex)
{
. . . (tratare excepie 2)
}
catch (Exception ex)
{
. . . (tratare excepie 3)
}
Exemplu final
S vedem cum arat n C# exemplul care implementeaz o stiv i o coad.
Vom crea un proiect de tip C# Console Appllication. Codul aplicaiei va fi:
using System;
using System.Collections.Generic;
using System.Text;
namespace list
{
class Program
{
static void Main(string[] args)
{
Baza st;
Baza cd;
st=new Stiva();
cd=new Coada();
st.Afisez();
st.PUSH(1);
st.PUSH(2);
st.Afisez();
st.POP();
st.Afisez();
Console.ReadLine();
cd.Afisez();
cd.PUSH(1);
cd.PUSH(2);
cd.Afisez();
cd.POP();
cd.Afisez();
Console.ReadLine();
}
public class Elem_lista
{
private int _val;
private Elem_lista _urmatorul;
public Elem_lista(int i)
{
_val = i;
_urmatorul = null;
}
public int val
{
get
{
return _val;
}
set
{
_val = value;
}
}
public Elem_lista urmatorul
{
get
{
return _urmatorul;
}
set
{
_urmatorul = value;
}
}
}
public abstract class Baza
{
private Elem_lista _cap;
public Baza()
{
_cap = null;
}
public virtual void PUSH(int i)
{
// nu stiu cum se defineste
}
public virtual int POP()
{
// nu stiu cum se defineste
return 0;
}
public virtual void Afisez()
{
Elem_lista ptr = new Elem_lista(0);
ptr = _cap;
if (ptr == null)
Console.WriteLine(" Structura vida");
while (ptr != null)
{
Console.WriteLine(ptr.val);
ptr = ptr.urmatorul;
}
}
public Elem_lista cap
{
get
{
return _cap;
}
set
{
_cap=value;
}
}
}
cap=ptr;
}
public override int POP()
{
int valret;
if (cap==null)
{
Console.WriteLine("Stiva goala");
return 0;
}
valret=cap.val;
cap=cap.urmatorul;
return valret;
}
public override void Afisez()
{
Console.WriteLine("Stiva contine");
base.Afisez();
}
}
public class Coada : Baza
{
public override void PUSH(int i)
{
Elem_lista elem_nou = new Elem_lista(i);
Elem_lista ptr = new Elem_lista(0);
if (cap == null)
cap = elem_nou;
else
{
ptr = cap;
while (ptr.urmatorul != null)
ptr = ptr.urmatorul;
ptr.urmatorul = elem_nou;
}
}
public override int POP()
{
int valret;
if (cap == null)
{
Console.WriteLine("Coada goala");
return 0;
}
valret = cap.val;
cap = cap.urmatorul;
return valret;
}
public override void Afisez()
{
Console.WriteLine("Coada contine");
base.Afisez();
}
}
}
...
}
...
}