P. 1
Manual POO Si Vizuala

Manual POO Si Vizuala

|Views: 68|Likes:
Published by Oana-Andreea Ciocan

More info:

Published by: Oana-Andreea Ciocan on Apr 26, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

11/03/2012

pdf

text

original

Cuprins 
I. PROGRAMARE ORIENTATĂ PE OBIECTE.............................................................................................. 3  I.1.  INTRODUCERE IN .NET.............................................................................................................................. 3  I.1.1.  Arhitectura .NET Framework .......................................................................................................... 4  I.1.2.  Compilarea programelor................................................................................................................. 4  I.1.3.  De ce am alege .NET? ..................................................................................................................... 5  I.2.  INTRODUCERE ÎN LIMBAJUL C# ................................................................................................................. 5  I.2.1.  Caracterizare................................................................................................................................... 5  I.2.2.  Crearea aplicaţiilor consolă............................................................................................................ 6  I.2.3.  Structura unui program C#.............................................................................................................. 8  I.2.4.  Sintaxa limbajului.......................................................................................................................... 10  I.2.4.6. Expresii şi operatori ......................................................................................................................... 12  I.2.6.9. Instrucţiunile try-catch-finally şi throw............................................................................................ 48  I.3.  PRINCIPIILE PROGRAMĂRII ORIENTATE PE OBIECTE ................................................................................. 75  I.3.1.  Evoluţia tehnicilor de programare ................................................................................................ 75  I.3.2.  Tipuri de date obiectuale. Încapsulare .......................................................................................... 76  I.3.3.  Supraîncărcare .............................................................................................................................. 78  I.3.4.  Moştenire ....................................................................................................................................... 79  I.3.5.  Polimorfism. Metode virtuale ........................................................................................................ 80  I.3.6.  Principiile programării orientate pe obiecte ................................................................................. 81  I.4.  STRUCTURA UNEI APLICAŢII ORIENTATĂ PE OBIECTE ÎN C#..................................................................... 81  I.4.1.  Clasă de bază şi clase derivate...................................................................................................... 82  I.4.2.  Constructori................................................................................................................................... 82  I.4.3.  Supraîncărcarea constructorilor şi definirea constructorilor în clasele derivate ......................... 83  I.4.4.  Destructor...................................................................................................................................... 84  I.4.5.  Metode ........................................................................................................................................... 84  I.5.  CLASE ŞI OBIECTE ................................................................................................................................... 88  I.5.1.  Clase .............................................................................................................................................. 88  I.6.  CLASE ŞI FUNCŢII GENERICE .................................................................................................................. 111  I.7.  DERIVAREA CLASELOR (MOŞTENIRE) .................................................................................................... 114  I.7.1.  Principiile moştenirii ................................................................................................................... 114  I.7.2.  Accesibilitatea membrilor moşteniţi ............................................................................................ 116  I.7.3.  Metode ......................................................................................................................................... 118  I.7.4.  Interfeţe........................................................................................................................................ 119  I.8.  TRATAREA EXCEPŢIILOR ÎN C#.............................................................................................................. 121  I.8.1.  Aruncarea şi prinderea excepţiilor.............................................................................................. 123  I.9.  POLIMORFISM ........................................................................................................................................ 126  I.9.1.  Introducere .................................................................................................................................. 126  I.9.2.  Polimorfismul parametric............................................................................................................ 127  I.9.3.  Polimorfismul ad-hoc .................................................................................................................. 128  I.9.4.  Polimorfismul de moştenire ......................................................................................................... 129  I.9.5.  Modificatorii virtual şi overide ......................................................................................... 130  I.9.6.  Modificatorul new ....................................................................................................................... 131  I.9.7.  Metoda sealed.......................................................................................................................... 132  II. PROGRAMARE VIZUALĂ ....................................................................................................................... 133  I....................................................................................................................................................................... 133  II ..................................................................................................................................................................... 133  II.1.  CONCEPTE DE BAZĂ ALE PROGRAMĂRII VIZUALE.............................................................................. 133  II.2.  MEDIUL DE DEZVOLTARE VISUAL C# (PREZENTAREA INTERFEŢEI) .................................................. 134  II.3.  ELEMENTELE POO ÎN CONTEXT VIZUAL ........................................................................................... 136  Barele de instrumente ................................................................................................................................. 138  II.4.  CONSTRUIREA INTERFEŢEI UTILIZATOR ............................................................................................ 143  II.4.1.  Ferestre........................................................................................................................................ 143  II.4.2.  Controale ..................................................................................................................................... 146  II.5.  APLICAŢII ......................................................................................................................................... 147  II.5.1.  Numere pare ................................................................................................................................ 147  II.5.2.  Proprietăţi comune ale controalelor şi formularelor: ................................................................. 149  II.5.3.  Metode şi evenimente................................................................................................................... 150 
1

II.5.4.  Obiecte grafice............................................................................................................................. 172  II.5.5.  Validarea informaţiilor de la utilizator ....................................................................................... 174  II.5.6.  MessageBox ................................................................................................................................. 175  II.5.7.  Interfaţă definită de către utilizator............................................................................................ 178  II.5.8.  Browser creat de către utilizator ................................................................................................. 186  II.5.9.  Ceas ............................................................................................................................................. 191  II.6.  ACCESAREA ŞI PRELUCRAREA DATELOR PRIN INTERMEDIUL SQL SERVER ....................................... 194  II.6.1.  Crearea unei baze de date. Conectare şi deconectare................................................................. 194  II.6.2.  Popularea bazei de date .............................................................................................................. 196  II.6.3.  Introducere în limbajul SQL ........................................................................................................ 197  II.7.  ACCESAREA ŞI PRELUCRAREA DATELOR CU AJUTORUL MEDIULUI VIZUAL........................................ 205  II.7.1.  Conectare şi deconectare............................................................................................................. 205  II.7.2.  Operaţii specifice prelucrării tabelelor ....................................................................................... 208  II.8.  ACCESAREA ŞI PRELUCRAREA DATELOR CU AJUTORUL ADO.NET................................................... 209  II.8.1.  Arhitectura ADO.NET ................................................................................................................. 210  II.8.2.  Furnizori de date (Data Providers) ............................................................................................. 211  II.8.3.  Conectare..................................................................................................................................... 211  II.8.4.  Comenzi ....................................................................................................................................... 213  II.8.5.  DataReader.................................................................................................................................. 213  II.8.6.  Constructori şi metode asociate obiectelor de tip comandă ........................................................ 215  II.8.7.  Interogarea datelor...................................................................................................................... 218  II.8.8.  Inserarea datelor ......................................................................................................................... 218  II.8.9.  Actualizarea datelor .................................................................................................................... 219  II.8.10.  Ştergerea datelor ........................................................................................................................ 220  II.8.11.  DataAdapter şi DataSet .............................................................................................................. 223  II.9.  APLICAŢIE FINALĂ ............................................................................................................................ 226 

2

I. Programare orientată pe obiecte I.1. Introducere in .NET

.NET este un cadru (Framework) de dezvoltare software unitară care permite realizarea, distribuirea şi rularea aplicaţiilor desktop Windows şi aplicaţiilor WEB. Tehnologia .NET pune laolaltă mai multe tehnologii (ASP, XML, OOP, SOAP, WDSL, UDDI) şi limbaje de programare (VB, C++, C#, J#) asigurând, totodată, atât portabilitatea codului compilat între diferite calculatoare cu sistem Windows, cât şi reutilizarea codului în programe, indiferent de limbajul de programare utilizat. .NET Framework este o componentă livrată împreună cu sistemul de operare Windows. De fapt, .NET 2.0 vine cu Windows Server 2003, se poate instala pe versiunile anterioare, până la Windows 98 inclusiv; .NET 3.0 vine instalat pe Windows Vista şi poate fi instalat pe versiunile Windows XP cu SP2 şi Windows Server 2003 cu minimum SP1. Pentru a dezvolta aplicaţii pe platforma .NET este bine să avem 3 componente esenţiale:

un set de limbaje (C#, Visual Basic .NET, J#, Managed C++, Smalltalk, Perl, Fortran, Cobol, Lisp, Pascal etc), un set de medii de dezvoltare (Visual Studio .NET, Visio), o bibliotecă de clase pentru crearea serviciilor Web, aplicaţiilor Web şi aplicaţiilor desktop Windows.

 

Când dezvoltăm aplicaţii .NET, putem utiliza:

Servere specializate - un set de servere Enterprise .NET (din familia SQL Server 2000, Exchange 2000 etc), care pun la dispoziţie funcţii de stocare a bazelor de date, email, aplicaţii B2B (Bussiness to Bussiness – comerţ electronic între partenerii unei afaceri). Servicii Web (în special comerciale), utile în aplicaţii care necesită identificarea utilizatorilor (de exemplu, .NET Passport - un mod de autentificare folosind un singur nume şi o parolă pentru toate site-urile vizitate) Servicii incluse pentru dispozitive non-PC (Pocket PC Phone Edition, Smartphone, Tablet PC, Smart Display, XBox, set-top boxes, etc.)

.NET Framework Componenta .NET Framework stă la baza tehnologiei .NET, este ultima interfaţă între aplicaţiile .NET şi sistemul de operare şi actualmente conţine:

Limbajele C#, VB.NET, C++ şi J#. Pentru a fi integrate în platforma .NET, toate aceste limbaje respectă nişte specificaţii OOP numite Common Type System (CTS). Ele au ca elemente de bază: clase, interfeţe, delegări, tipuri valoare şi referinţă, iar ca mecanisme: moştenire, polimorfism şi tratarea excepţiilor.
3

 I. Astfel.NET Framework este formată din compilatoare. fire de execuţie. ce execută instrucţiunile IL rezultate în urma compilării. CLR include o maşină virtuală asemănătoare cu o maşină Java.NET conform Common Language Specification (CLS) este compilat în Microsoft Intermediate Language (MSIL sau IL). Fişierele corespunzătoare se află. clasele şi obiectele create într-un limbaj specific .NET pot fi utilizate cu succes în altul. în general. Codul astfel obţinut are extensia "exe".NET să fie din ce în ce mai rapide. 4 . Arhitectura . El recunoaşte secvenţele de cod pentru care s-a obţinut deja codul maşină adecvat. (corespunzător versiunii instalate) FCL I. colecţii etc. NET\Framework\V2.compilatoare JIT) CLR Componenta . dar nu este direct executabil.) Common Language Runtime (execepţii. permiţând reutilizarea acestuia fără recompilare. ceea ce face ca. Faptul că programul IL produs de diferitele limbaje este foarte asemănător are ca rezultat interoperabilitatea între aceste limbaje. XML etc.1.NET. aplicaţiile . securitate. utilizată de toate cele 4 limbaje. SQL. Compilatorul JIT analizează codul IL corespunzător apelului unei metode şi produce codul maşină adecvat şi eficient. validări de tipuri.NET. ci respectă formatul unic MSIL. pe parcursul rulării.1. Ansamblul de biblioteci necesare în realizarea aplicaţiilor desktop sau Web.) Framework Base Classes (IO.1. în directorul C:\WINDOWS\Microsoft. CTS face parte din CLR.2. Platforma comună de executare a programelor numită Common Language Runtime (CLR). Maşina foloseşte un compilator special JIT (Just In Time).NET Framework Servicii WEB Formulare Data and XML classes (ADO. biblioteci şi alte executabile utile în rularea aplicaţiilor . numit Framework Class Library (FCL). Compilarea programelor Un program scris într-unul dintre limbajele .0….

Principiile de bază ale programării orientate pe obiecte (ÎNCAPSULARE. Caracterizare Limbajul C# a fost dezvoltat de o echipă restrânsă de ingineri de la Microsoft.NET fiind acela de eliberare automată a zonelor de memorie asociate unor date devenite inutile – Garbage Collection).NET. C# este un limbaj simplu. Unele funcţiuni (cum ar fi accesul 5 .htm ). Sunt o serie de tipuri noi de date sau funcţiuni diferite ale datelor din C++. trebuie spus că . unele funcţiuni au fost adăugate (de exemplu. În mare.org/publications/standards/Ecma-335. El permite programarea structurată. conform perceptelor moderne ale programării profesioniste. Linux. Tot .Forms conţine instrumente (controale) ce permit implementarea elementelor interfeţei grafice cu utilizatorul.mono-project. permite realizarea desenelor sau a altor elemente grafice.2.1. diversificate (tipul struct). echipă din care s-a evidenţiat Anders Hejlsberg (autorul limbajului Turbo Pascal şi membru al echipei care a proiectat Borland Delphi). POLIMORFISM) sunt elemente fundamentale ale programării C#. elementele interfeţei grafice. Introducere în limbajul C# I.NET vă oferă clase care efectuează majoritatea sarcinilor uzuale cu care se confruntă programele şi care plictisesc şi fură timpul programatorilor. Mac OS X şi alte sisteme de operare (http://www. modificate (tipul string) sau chiar eliminate (moştenirea multiplă şi pointerii către funcţii). I. Spaţiul de nume System.ecma-international. interfeţe şi delegări). ceea ce permite rularea aplicaţiilor .2. De ce am alege . Solaris.NET Framework este implementarea unui standard numit Common Language Infrastructure (http://www. reducând astfel timpul necesar dezvoltării aplicaţiilor. modulară şi orientată obiectual.În plus. şi pe unele tipuri de Unix. puteţi proiecta şi dezvolta rapid şi interactiv.Windows. MOŞTENIRE. cu circa 80 de cuvinte cheie şi 12 tipuri de date predefinite. oferă acces uşor la baze de date. iar în spiritul realizării unor secvenţe de cod sigure (safe).3.1. Ca un element de portabilitate. limbajul moşteneşte sintaxa şi principiile de programare din C++.com/Main_Page ). în afară de Windows. Folosind aceste controale. CLR se ocupă de gestionarea automată a memoriei (un mecanism implementat în platforma . I.NET? În primul rând pentru că ne oferă instrumente pe care le putem folosi şi în alte programe.

Când creaţi o aplicaţie consolă. dar secvenţele de cod corespunzătoare se consideră „nesigure”. În cazul nostru. eventual mediul free Microsoft Visual C# 2008 Express Edition de la adresa http://www. se generează un fişier cu extensia .com/express/download/ După lansarea aplicaţiei.cs. Extensia cs provine de la C Sharp. Redenumirea lui se poate realiza 6 . Crearea aplicaţiilor consolă Pentru a realiza aplicaţii consolă (ca şi cele din Borland Pascal sau Borland C) în mediul de dezvoltare Visual Studio. trebuie să instalăm o versiune a acestuia.direct la memorie folosind pointeri) au fost păstrate.microsoft.2.cs. din meniul File se alege opţiunea NewProject apoi alegem ConsoleApplication. I.2. s-a generat fişierul Primul. modificând numele aplicaţiei în caseta Name.

cursorul din program se poziţionează pe linia conţinând eroarea. Efectuând dublu-clic pe fiecare eroare în parte. using System. ajutorul contextual. using System. using System. namespace ConsoleApplication1 { class Program { static void Main(string[] args) { } } } Completaţi funcţia Main cu următoarea linie de program: Console.WriteLine("Primul program"). Încetarea urmăririi pas cu pas (Stop Debugging Shift+F5) permite ieşirea din modul depanare şi revenirea la modul normal de lucru.Collections. În cazul în care aveţi erori. Veţi observa că în scrierea programului sunteţi asistaţi de IntelliSense. Pentru compilarea programului. Toate opţiunile şi rulare şi depanare se găsesc în meniul Debug al mediului de programare. pe care o puteţi afişa cu ajutorul combinaţiei de taste Ctrl+W. Rularea programului se poate realiza în mai multe moduri:  rapid fără asistenţă de depanare (Start Without Debugging Ctrl+F5)    rapid cu asistenţă de depanare (Start Debugging F5 sau cu butonul din bara de instrumente) rulare pas cu pas (Step Into F11 şi Step Over F10) rulare rapidă până la linia marcată ca punct de întrerupere (Toggle Breakpoint F9 pe linia respectivă şi apoi Start Debugging F6).S sau din meniul View.Linq.din fereastra Solution Explorer. Codul sursă generat este : using System. selectaţi Build din meniul principal sau apăsaţi tasta F6.Generic.Text. 7 . acestea sunt afişate în fereastra Error List.

Este obligatoriu ca doar una din aceste clase să conţină un „punct de intrare” (entry point). Vom prezenta şi noi acest exemplu adaptat la limbajul C#: 1 2 3 4 5 6 7 8 9 10 11 12 using System. şi anume metoda (funcţia) Main. } } } O aplicaţie C# este formată din una sau mai multe clase. Structura unui program C# Majoritatea cărţilor care tratează limbaje de programare încep cu un exemplu.WriteLine("Hello World!").Icoanele din IntelliSense şi semnificaţia lor I. apărut pentru prima dată în ediţia din 1978 a cărţii „The C Programming Language” a lui Brian W. grupate în spaţii de nume (namespaces). Kernighan şi Dennis M. Ritchie. „părinţii” limbajului C. 8 .3. devenit celebru.2. namespace HelloWorld { class Program { static void Main() { Console.

 Clasa (class), în termeni simplificaţi, reprezintă principalul element structural şi de organizare în limbajele orientate spre obiecte, grupând date cât şi funcţii care prelucrează respectivele date.  Spaţiul de nume (Namespaces): din raţiuni practice, programele mari, sunt divizate în module, dezvoltate separat, de mai multe persoane. Din acest motiv, există posibilitatea de a apărea identificatori cu acelaşi nume. Pentru a evita erori furnizate din acest motiv, în 1955 limbajul C++ introduce noţiunea şi cuvântul cheie namespace. Fiecare mulţime de definiţii dintr-o librărie sau program este grupată într-un spaţiu de nume, existând astfel posibilitatea de a avea într-un program definiţii cu nume identic, dar situate în alte spaţii de nume. În cazul în care, într-o aplicaţie, unele clase sunt deja definite, ele se pot folosi importând spaţiile de nume care conţin definiţiile acestora. Mai menţionăm faptul că un spaţiu de nume poate conţine mai multe spaţii de nume.

Să comentăm programul de mai sus: linia 1: este o directivă care specifică faptul că se vor folosi clase incluse în spaţiul de nume System. În cazul nostru, se va folosi clasa Console. linia 3: spaţiul nostru de nume linia 5: orice program C# este alcătuit din una sau mai multe clase linia 7: metoda Main, „punctul de intrare” în program linia 9: clasa Console, amintită mai sus, este folosită pentru operaţiile de intrare/ieşire. Aici se apelează metoda WriteLine din această clasă, pentru afişarea mesajului dorit pe ecran. În C#, simplificat vorbind, un program poate fi privit ca având mai multe „straturi”: avem cod în interiorul metodelor, care, la rândul lor, se află în interiorul claselor, aflate în interiorul namespaces-urilor. Convenţie: S-a adoptat următoarea namespace class metodă cod

convenţie de scriere: în cazul în care folosim nume compuse din mai multe cuvinte, fiecare cuvânt este scris cu majusculă: HelloWorld, WriteLine. Această convenţie poartă numele de Convenţie Pascal. Asemănătoare este Convenţia cămilă, cu diferenţa că primul caracter din primul cuvânt este literă mică.

9

I.2.4.

Sintaxa limbajului

Ca şi limbajul C++ cu care se înrudeşte, limbajul C# are un alfabet format din litere mari şi mici ale alfabetului englez, cifre şi alte semne. Vocabularul limbajului este format din acele „simboluri” cu semnificaţii lexicale în scrierea programelor: cuvinte (nume), expresii, separatori, delimitatori şi comentarii.

I.2.4.1. Comentarii
Limbajul C# admite trei tipuri de comentarii:

comentariu pe un rând prin folosirea //. Tot ce urmează după caracterele // sunt considerate, din acel loc până la sfârşitul rândului, drept comentarii.
// Acesta este un comentariu pe un singur rand

comentariu pe mai multe rânduri prin folosirea /* şi */. Orice text cuprins între simbolurile menţionate mai sus se consideră a fi comentariu. Simbolurile /* reprezintă începutul comentariului, iar */ sfârşitul respectivului comentariu.
/* Acesta este un comentariu care se intinde pe mai multe randuri */

creare document în format XML folosind ///.

Nepropunându-ne să intrăm în

amănunte, amintim că XML (eXtensible Markup Language) a fost proiectat în scopul transferului de date între aplicaţii pe Internet, fiind un model de stocare a datelor nestructurate şi semi-structurate.

I.2.4.2. Nume Definiţie: Prin nume dat unei variabile, clase, metode etc. înţelegem o succesiune de caractere care îndeplineşte următoarele reguli:
  

numele trebuie să înceapă cu o literă sau cu unul dintre caracterele ”_” şi ”@”; primul caracter poate fi urmat numai de litere, cifre sau un caracter de subliniere; numele care reprezintă cuvinte cheie nu pot fi folosite în alt scop decât acela pentru care au fost definite; cuvintele cheie pot fi folosite în alt scop numai dacă sunt precedate de @;
10

două nume sunt distincte dacă diferă prin cel puţin un caracter (fie el şi literă mică ce diferă de aceeaşi literă majusculă).

Convenţii pentru nume:

în cazul numelor claselor, metodelor, a proprietăţilor, enumerărilor, interfeţelor, spaţiilor de nume, fiecare cuvânt care compune numele începe cu majusculă; în cazul numelor variabilelor, dacă numele este compus din mai multe cuvinte, primul începe cu minusculă, celelalte cu majusculă.

I.2.4.2. Cuvinte cheie în C#
Cuvintele cheie sunt identificatori predefiniţi cu semnificaţie specială pentru compilator. Definim în C# următoarele cuvinte cheie: abstract byte class delegate event fixed if internal new override readonly short struct try unsafe volatile as case const do explicit float implicit is null params ref sizeof switch typeof ushort while base catch continue double extern for in lock object private return stackalloc this uint using bool char decimal else false foreach int long operator protected sbyte static throw ulong virtual break checked default enum finally goto interface namespace out public sealed string true unchecked void

Pentru a da semnificaţii specifice codului, în C# avem şi cuvinte cheie contextuale:

ascending get on value

by group orderby where

descending into partial yield

equals join select

from let set

În general, cuvintele cheie nu pot fi folosite în programele pe care le scriem, dându-le o altă semnificaţie. În cazul în care, totuşi, dorim să le dăm o altă semnificaţie, va trebui să le scriem cu simbolul „@” ca prefix. Datorită neclarităţilor care pot să apară, se va evita folosirea cuvintelor rezervate în alte scopuri.

11

I.2.4.3. Constante
În C# există două modalităţi de declarare a constantelor: folosind const sau folosind modificatorul readonly. Constantele declarate cu const trebuie să fie iniţializate la declararea lor. Exemplul 1:
const int x; const int x = 13; //gresit, constanta nu a fost initializata //corect

Constantele declarate cu ajutorul lui readonly sunt doar variabilele membre ale claselor, ele putând fi iniţializate doar de către constructorii claselor respective.

Exemplul 2:
readonly int x; readonly int x = 13; //corect //corect

I.2.4.4. Variabile

O variabilă în C# poate să conţină fie o valoare a unui tip elementar, fie o referinţă la un obiect. C# este „case sensitive”, deci face distincţie între litere mari şi mici.

Exemplul 3:
int Salut; int Azi_si_maine; char caracter;

I.2.4.6. Expresii şi operatori
Definiţie: Prin expresie se înţelege o secvenţă formată din operatori şi operanzi. Un operator este un simbol ce indică acţiunea care se efectuează, iar operandul este valoarea asupra căreia se execută operaţia. Operatorii se împart în trei categorii:
12

   Unari: . evaluarea expresiei se realizează de la stânga la dreapta.acţionează asupra unui singur operand Binari: . Indicaţii:  Sintaxa acestui operator este: (condiţie) ? (expr_1): (expr_2) cu semnificaţia se evaluează condiţie. În cazul în care sunt mai mulţi operatori cu aceeaşi prioritate. În cazul în care într-o expresie nu intervin paranteze. Tabelul de priorităţi: Prioritate 0 1 2 3 4 5 6 7 8 9 10 11 12 13 Tip Primar Unar Multiplicativ Aditiv De deplasare Relaţional De egalitate AND (SI) logic XOR (SAU exclusiv) logic OR (SAU) logic AND (SI) condiţional OR (SAU) condiţional Condiţional(ternar) atribuire simplă atribuire compusă Operatori ( ) [ ] f() . altfel expr_2 int. să se decidă dacă un număr citit de la tastatură este pozitiv sau negativ.acţionează asupra a trei operanzi.new typeof sizeof checked unchecked -> + . În tabelul alăturat prioritatea descreşte de la 0 la 13.Parse converteşte un şir la int  13 .acţionează între doi operanzi Ternari: .! ~ ++x --x (tip) true false & sizeof * / % + << >> < > <= >= is as == != & ^ | && || ?: = *= /= %= += -= ^= &= <<= >>= Asociativitate → → → → → → → → → → → → ← ← |= Exemplul 4: folosind operatorul ternar ?:. dacă ea este adevărată se execută expr_1. există un singur operator ternar şi acesta este ?: În C# sunt definiţi mai mulţi operatori. x++ x-. operaţiile se execută conform priorităţii operatorilor.

ToInt32 converteşte un şir la Int32 using System.Write(a). negativ".ReadLine()).ReadLine().Linq.ToInt32(Console. namespace OperatorConditional { class Program { static void Main(string[] args) { int a.Generic.WriteLine("este impar").Parse(Console. Console. Console. Observaţie: Convert. a = int.WriteLine("este par"). else System.Console.ReadLine()). namespace primul_proiect { class Program { static void Main(string[] args) { int x. x = Convert. using System. } } } 14 .Text.Generic. if (x % 2 == 0) Console.using System. să se verifice dacă un număr este par sau impar. Console.Text. using System.Collections.Collections. pozitiv" : " este nr. string rezultat. using System. using System. using System. rezultat = (a > 0) ? " este nr. } } } În urma rulării programului obţinem: Exemplul 5: Folosind operatorul %.Write(rezultat).

WriteLine("{0. v1 & v2). se poate folosi următoarea formă a lui WriteLine(): WriteLine("sir". varn). v2 = true.WriteLine("{0. Opţiuni de afişare Pentru a avea control asupra modului de afişare a informaţiei numerice.6}" + " & " + "{0.6}". + "{0.ReadKey(). + "{0.Exemplul 6: Următorul program afişează la consolă tabelul de adevăr pentru operatorul logic &. Console.6}" + " = " v1. v1 = false. v2.Text. v2. System. v2 = true. System. v2.Collections. } } } + "{0. Console. v1 & v2).Linq. + "{0.6}" + " & " + "{0. v2.Generic.6}". v2.6}" + " & " + "{0.7.6}" + " = " v1.6}". Console. System.2.WriteLine("{0.6}" + " = " v1. using using using using System. v1 & v2).var2.6}" + " = " v1. v1 = false. namespace Exemplul_6 { class Program { static void Main(string[] args) { bool v1.6}" + " & " + "{0.var1. v2 = false.4.6}". Console. unde „sir” este format din două elemente:  caracterele afişabile obişnuite conţinute în mesaje 15 . v1 & v2). v2 = false.WriteLine("{0. Console. v1 = true. v1 = true.…. I.

###}".Text. namespace Exemplul_8 { class Program { static void Main(string[] args) { Console.WriteLine("Valoarea constantei matematice PI este {0:#.Generic.Collections. Console.Math.PI). namespace Exemplul_7 { class Program { static void Main(string[] args) { int a.WriteLine("a={0} b={1}".Text. using System. specificatorii de format ce au forma generală {nr_var. using System. b = ++c. c = 5. formatul de afişare ales #. a = c++. a. width stabileşte lăţimea câmpului de afişare.Generic.b).### va produce afişarea cu trei zecimale a constantei PI using System. using System. iar fmt stabileşte formatul Exemplul 7: using System. } } } 16 . b.width:fmt} unde nr_var precizează numărul variabilei (parametrului) care trebuie afişată începând cu 0.Collections. } } } Exemplul 8: în acest exemplu. using System.

} } } 17 . Console. System.I. a. // byte intreg fara semn pe 8 biţi byte b = 20.WriteLine("Suma intregilor pe 8 biţi se reprezinta pe 64 biţi"). Exemplul 9: Exemplul următor realizează suma a două valori numerice fără semn cu reprezentare pe 8 biţi. System.Text. Conversia implicită se efectuează (automat) doar dacă nu este afectată valoarea convertită.WriteLine("{0} + {1} = {2}".8. Rezultatul va fi reţinut pe 64 biţi using using using using System. // intreg cu semn pe 64 biţi c = a + b. b. long c. c).Generic.Linq. namespace Exemplul_9 { class Program { static void Main(string[] args) { byte a = 13.Collections.2. Conversii În C# există două tipuri de conversii numerice:   implicite explicite. System.4. Console.

decimal int. byte. byte. int. int. ulong. decimal int. byte. uint. uint. float. atunci când nu există posibilitatea unei conversii implicite. ulong. short. long.1. short. char. ushort. float. uint. float. uint. byte. Conversiile implicite Regula după care se efectuează conversiile implicite este descrisă de tabelul următor: din sbyte byte short ushort int uint long char float ulong în short. byte. double. ushort. int. int. decimal sbyte. ulong. Conversia explicită Se realizează prin intermediul unei expresii cast (care va fi studiată mai târziu). double. short. int. uint. uint. ulong. byte. double. char sbyte. double. double. float. char. ushort. ushort. decimal sbyte. ulong. float. ushort. long. int. float. long. ushort. decimal long. char sbyte. char sbyte. ushort.2. short. char sbyte. byte. long. decimal long. double. float. ulong. decimal I. short.8. int. long. char sbyte. decimal float. ulong. ulong. long. long. ulong. uint. short. long. char sbyte. byte.2.8. uint. short. uint. ulong. double 18 .4. ushort. char.4.2. byte.I. short. float. decimal double float. uint. char sbyte. uint. long. din sbyte byte short ushort int uint long ulong char float double decimal în byte. ulong. double. float. decimal short. ushort.byte. int. decimal ushort. short sbyte. char sbyte. double. double. ushort. int.

} } } în urma rulării programului. a. using System.evident eronat . namespace Exemplul_10 { class Program { static void Main(string[] args) { int a = 5. reprezentat ca real datorita operatorului cast\nde conversie explicita").WriteLine("{0} / {1} = {2}".Exemplul 10: using System. c). int b = 2. float c. Console. Conversia din tipul numeric în şir de caractere se realizează cu metoda ToString a clasei Object Exemplul 11: int i = 13 string j = i. 19 .Collections. c = (float)a / b. //operatorul cast Console. b. se va obţine: În cazul în care nu s-ar fi folosit operatorul cast.ar fi fost:  Des întâlnită este conversia din tipul numeric în şir de caractere şi reciproc.Text.WriteLine("Catul intregilor. rezultatul .ToString().Generic. using System.

Exemplul 13: Exemplul de mai jos prezintă mai multe tipuri de conversii using using using using System. Exemplul 12: string s = "13". System. iv. bv. strv.WriteLine("int si short spre float {0} + {1} = {2}\n".Parse(s). Console. string strrez.ToInt64(strv). fv = 13.WriteLine("Explicite:"). Console. Console.WriteLine("float si short spre double {0} + {1} = {2}". Console. frez = iv + sv. dv = 87. Console.Generic. float frez. } } } 20 .WriteLine("bool si float spre string folosind ToString \"{0}\" + \"{1}\" = {2}". int n = int. lrez).WriteLine("Exemple de conversii:\n"). long lrez.Text. System.Conversia din şir de caractere în număr se realizează cu ajutorul metodei Parse tot din clasa Object. int iv = 123.47F.WriteLine("float spre short folosind cast {0} spre {1}". drez). System.Linq.ToString(frez). sv.WriteLine("int si string cu ToInt64 spre long {0} + {1} = {2}". sv. fv. strrez). frez. Console. fv. strrez = Convert. Console. srez). bool bv = false.86. Console. drez = fv + sv. double drez.Collections. lrez = iv + Convert.WriteLine("Implicite:"). namespace Exemplul_13 { class Program { static void Main(string[] args) { short srez. sv = 13. srez = (short)fv. frez). iv.ToString(bv) + Convert. strv = "15".

se produce ambalarea în interiorul unei instanţe de tip referinţă. care se păstrează în memoria heap. care va conţine valoarea 13.4.3. Conversii boxing şi unboxing Datorită faptului că în C# toate tipurile sunt derivate din clasa Object (System. valoare care va fi stocată pe stivă. //boxing explicit sau int i = 13. care se păstrează pe stivă. object ob = i. Prin conversia boxing a unui tip valoare. heap int 13 21 . object ob = (object)i. i stiva 13 int i=13.I. prin conversiile boxing (împachetare) şi unboxing (despachetare) este permisă tratarea tipurilor valoare drept obiecte şi reciproc. Unboxing permite convertirea unui obiect în tipul valoare echivalent.2. Exemplul 14: Prin boxing. Linia a doua creează o referinţă către un obiect alocat în heap. care va conţine atât valoarea 13. la clasa Object. cât şi informaţia referitoare la tipul de dată conţinut.8.Object). variabila i este asignata unui obiect ob: int i = 13. ob object ob=i. //boxing implicit În prima linie din exemplu se declară şi se iniţializează o variabilă de tip valoare.

Console. Console. i=6.Collections. using System. Se poate determina tipul pentru care s-a făcut împachetarea folosind operatorul is: Exemplul 15: int i = 13. Exemplul 16: using System.ReadLine().Text. i = (int)ob. //boxing implicit //unboxing explicit 22 . using System. obiectul ob poate fi asignat variabilei întregi i: int i = 13. } Prin boxing se creează o copie a valorii care va fi conţinută.WriteLine("Impachetarea s-a facut pentru int").WriteLine("In ob se pastreaza {0}". ob). object ob = i. i).Generic. } } } În urma rulării se obţine: Exemplul 17: Prin conversia de tip unboxing. object ob = i. Console. if (ob is int) { Console. object ob = i. namespace ConsoleApplication1 {class Program {static void Main(string[] args) { int i = 13.WriteLine("Valoarea actuala a lui i este {0}".

Parse(şir) Observaţie: În cazul în care şirul de caractere nu reprezintă un număr valid.Parse(şir) sau Int64. const long b = 100000. double d = 3.Parse("13"). s = "" + d. s). \tSTRING"). c. Exemplul 18: using using using using System. const int a = 13.WriteLine("----------------------"). conversia acestui şir la număr va eşua. namespace Exemplul_18 { class Program { static void Main(string[] args) { string s. s = "" + c.WriteLine("float\t{0} \t{1}".15F. int a1.Parse(şir) sau Float. Console.I.4. s = "" + b.Collections.WriteLine("----------------------"). Console. System. Console.WriteLine("long\t{0} \t{1}". System.WriteLine("\nSTRING\tVAL \tTIP"). Console. b.Generic.1415. Console.Parse(şir) sau Int32. Console.4. a.Parse(şir) sau Double. Console. Conversii între numere şi şiruri de caractere Limbajul C# oferă posibilitatea efectuării de conversii între numere şi şiruri de caractere.Parse(şir) double.WriteLine("CONVERSII\n"). adică din şir de caractere în număr. System.WriteLine("double\t{0} \t{1}". Sintaxa pentru conversia număr în şir de caractere: număr  şir “” + număr Pentru conversia inversă. s). d. s = "" + a. const float c = 2.8. s).2. Console.Linq.Parse(şir) long. Console.Text. 23 .WriteLine("TIP\tVAL.WriteLine("int\t{0} \t{1}". s). a1 = int.Parse(şir) float. sintaxa este: şir şir şir şir     int long double float int.

double d2. Console.WriteLine("{0}\t{1} \tfloat".array 24  tipuri referinţă - . c2 = float. d2 = double. } } } I. a1). Console.WriteLine("{0}\t{1}\tdouble".Globalization. b2 = long. int. Tipuri de date În C# există două categorii de tipuri de date:  tipuri valoare - tipul simplu predefinit: byte.2. float etc. b2).InvariantCulture).1415". "3. float c2. Console.struct tipul clasă – class tipul interfaţă – interface tipul delegat – delegate tipul tablou .Parse("3. d2).1415".WriteLine("{0}\t{1} \tlong".WriteLine("{0}\t{1}\tint". char.ReadKey().15".Parse("1000").Parse("2. "2.15").CultureInfo.Console. tipul enumerare – enum tipul structură . c2). "13". long b2. Console.5. "1000". System.

sb.  Pentru tipurile valoare.v este {0}. este copiată referinţa în variabila 25 .v este {0} prin initializare. Intreg sb = sa. se face o copie a datelor în variabila destinaţie care nu mai este legată de variabila iniţială.v este {0}.WriteLine("sa.Generic. Console. // se initializeaza prin copiere variabila sb Console.ValueType.v).v = 10. pentru tipurile referinţă. sa. Exemplul 19: using System. Console.WriteLine("sb.WriteLine("sb. sb.v).ReadLine(). la atribuire.".". Console. namespace ExempluTipuriValoare { public struct Intreg { public int v.Object  Toate tipurile valoare sunt derivate din clasa System.v). referin ele sunt null şi trebuie alocată explicit memorie pentru obiectele propriu-zise.v = 13. Console. using System.v). sa. derivată la rândul ei din clasa Object (alias pentru System.WriteLine("sa. } } }  Spre deosebire de tipurile valoare. declararea unei variabile nu implică automat alocarea de spaţiu: iniţial. sa. variabilele conţin valoarea implicită specifică tipului.Collections.Object). Acest proces se numeşte transmitere prin valoare. Observaţie: Toate tipurile de date sunt derivate din tipul System.v este {0}. declararea unei variabile implică şi alocarea de spaţiu. sau value semantics.".". using System. Dacă iniţial. sa. } class Program { static void Main(string[] args) { Intreg sa = new Intreg().Text. la atribuire. În plus.

Linq. b). Console.WriteLine("a este '{0}'. System.destinaţie.ReadLine(). Console.2.". Exemplul 20: Pentru exemplificarea celor de mai sus. vom folosi clasa StringBuilder.Collections.1. Tipul valoare I. Console.".WriteLine("a este '{0}' prin atribuirea unei noi valori.". a = null. using using using using System. dar obiectul spre care indică rămâne acelaşi (aliasing).Append("Salut").1. namespace ExempluTipuriReferinta { class Program { static void Main(string[] args) { StringBuilder a = new StringBuilder(). pentru tipurile referinţă. StringBuilder b = a.5. b). System.Text. class etc.5.1. Tipuri predefinite Limbajul C# conţine un set de tipuri predefinite (int. } } } I.Generic.).". Aceste reguli poarta denumirea de reference semantics. struct. a). System.2. Console. a.WriteLine("b este '{0}' prin initializare. bool etc. 26 . Console.WriteLine("b este '{0}'. a).) şi permite definirea unor tipuri proprii (enum.

UL.Int16 System. uint. Ul.Int32 System. U L. pe 64 biţi tip cu virgulă mobilă. long.Sbyte System. 4294967295 0. lU.79769313486232E+308. pe 128 biţi (96 pentru mantisă). 255 0. pe 16 biţi tip zecimal. pe 16 biţi tip întreg cu semn pe.79769313486232E+308 -79228162514264337593543950335.Double System. lu. 53 pentru mantisă) tip boolean tip caracter din setul Unicode. ulong uint. LU. pe 16 biţi tip întreg fără semn. pe 64 biţi (11 pentru exponent. 2147483647 -9223372036854775808. L ul. ulong ulong 27 .402823E+38. pe 8 biţi tip întreg cu semn. 32767 -2147483648. pe 32 biţi (8 pentru exponent.Char System. 65535 0.String System.Uint64 System. 1. 3.Decimal O valoare se asignează după următoarele reguli: Sufix nu are u.Tipuri simple predefinite Tip object string sbyte short int long byte ushort uint ulong float double bool char decimal Descriere rădăcina oricărui tip secvenţă de caractere Unicode tip întreg cu semn. pe 8 biţi tip întreg fără semn.Byte System. 18446744073709551615 -3. ulong long. 9223372036854775807 0. 28 de cifre semnificative Domeniul de valori pentru tipurile numerice: Tip sbyte short int long byte ushort uint ulong float double decimal Domeniul de valori -128. Lu Tip int.402823E+38 -1. simplă precizie. 32 biţi tip întreg cu semn. 24 pentru mantisă) tip cu virgulă mobilă. dublă precizie.Uint32 System.Int64 System. pe 64 de biţi tip întreg fără semn.Int16 System. pe 32 biţi tip întreg fără semn.Single System.Boolean System. 127 -32768. 79228162514264337593543950335 Alias pentru tipul struct din spaţiul de nume System System.

234.1.5. ulong c = 12. Specificarea tipului se face după numele enumerării: [atribute][modificatori]enum NumeEnumerare [: Tip] { lista } În ceea ce urmează. b }   În acest exemplu. long b = 13L.2. ulong d = 15U. double i = 1. operatori. 28 . Folosirea tipului enumerare impune următoarele observaţii:  în mod implicit. decimal j = 1.234M. valorile folosite pentru iniţializări trebuie să facă parte din domeniul de valori al tipului enum nu se admit referinţe circulare enum ValoriCirculare { a = b. I.Enum. asemănător cu cel din C++. bool cond2 = false.234F. tipul structură poate să conţină declaraţii de constante. valoarea primului membru al enumerării este 0.2. double h = 1. ulong f = 17UL. indexatori. ulong e = 16L.234D. câmpuri.ValueType. acesta este considerat implicit int. vom considera enum fără elementele opţionale. metode. iar fiecare variabilă care urmează are valoarea (implicită) mai mare cu o unitate decât precedenta. În cazul în care nu se specifică tipul enumerării. derivată din System. Tipul enumerare Tipul enumerare. se defineşte de către utilizator. a depinde explicit de b. float g = 1.  Enumerările nu pot fi declarate abstracte şi nu pot fi derivate. bool cond1 = true. constructori sau tipuri imbricate.Exemplul 21: string s = “Salut!” long a = 10. Orice enum este derivat automat din clasa System. sunt asociate unor valori numerice. proprietăţi. Acest tip permite utilizarea numelor care. iar b depinde de a implicit Asemănător celor cunoscute din C++.

Februarie.(int)lunaAnului.2. folosind structura System. Iunie. August. Sunt cazuri în care se doreşte ca."). nullable. Concret. la declarare. o declaraţie de forma: System.WriteLine("Luna Mai este a {0}".Nullable<T>. namespace tipulEnum {class Program { enum lunaAnului { Ianuarie = 1. 29 . sunt tipuri valoare pentru care se pot memora valori posibile din aria tipurilor de bază.ReadLine(). Mai.Mai + luna din an. Decembrie } static void Main(string[] args) { Console. Martie. aceasta conţine valoarea implicită a tipului. Octombrie. Aprilie. eventual şi valoarea null. Iulie.Exemplul 22: using System. Console.1. Noiembrie. valoarea implicită a variabilei să fie nedefinită. este echivalentă cu T? var.3. Tipuri nulabile Tipurile nulabile.Nullable<T> var.5. În C# există o astfel de posibilitate. unde T este un tip valoare. Am văzut mai sus că pentru tipurile valoare. la declararea unei variabile. } } } " I. Septembrie.

Console. in. continue. rezultat).6. else Instructiuni_B. I. else. b. b.2. I.ToInt32(Console. goto. Exemplul 23: Citindu-se două numere întregi.2. a = Convert. care indică dacă valoarea internă este diferită sau nu de null proprietatea Value. Console. else rezultat = "numere egale".ToInt32(Console. namespace Exemplul_23 { class Program { static void Main(string[] args) { int a. s-a mai introdus operatorul binar ?? a ?? b cu semnificaţia: dacă a este null b este evaluat şi constituie rezultatul expresiei. for. a. switch. } } } 30 . care va conţine valoarea propriu zisă.Write("Dati al doilea numar intreg : "). altfel rezultatul este a. Console.1.Aceste tipuri nulabile conţin două proprietăţi:   proprietate HasValue. case.WriteLine("Rezultatul comparatiei lui {0} cu {1} este \"{2}\"". default.Write("Dati primul numar intreg : "). să se decidă care dintre ele este mai mare using System. Instrucţiunea if Instrucţiunea if are sintaxa: if (conditie) Instructiuni_A. break.  Legat de această noţiune. else if (a < b) rezultat = "primul este mai mic". foreach.ReadLine()).6.ReadLine()). if (a > b) rezultat = "primul este mai mare". do. while. string rezultat. de iteraţie şi de control Ne referim aici la instrucţiunile construite folosind cuvintele cheie: if. Instrucţiuni condiţionale. b = Convert.

y2. M3(x3. Console. Punctele M1(x1. date prin coordonatele lor întregi. double E = (x2 .y1). x2. y3 = Convert. Console.ToDouble(System.ReadLine()). x3 = Convert.WriteLine("Puncte necoliniare"). Console.ToDouble(System. x3.Write("Ordonata : ").Linq.Write("Abscisa : "). M2 şi M3. y1 = Convert.ReadLine()). Console. Console.x1) * (y3 .Write("Abscisa : ").Console. System.x1) * (y2 .ReadLine()). Console.y3) sunt coliniare x1  x2 y1 1 y2 1 = 0 y3 1 x3  E=(x2-x1)(y3-y1)-(x3-x1)(y2-y1)=0 using using using using System.Write("Abscisa : ").Exemplul 24: Să se verifice dacă 3 puncte din plan M1.WriteLine("Puncte coliniare").ToDouble(System. x2 = Convert.Generic. y1.y2).Console.Console. M2(x2. else Console. Console. } } } 31 . y3. Console. Console.Console. y2 = Convert.ReadLine()).Write("Ordonata : ").(x3 . namespace Exemplul_24 { class Program { static void Main(string[] args) { double x1. System.Console.Collections. System.Write("Ordonata : ").y1) . x1 = Convert.ToDouble(System.Text.WriteLine("Coordonatele celui de-al doilea punct:").y1). if (E == 0) Console.ReadLine()).Console.WriteLine("Coordonatele primului punct:").ReadLine()).WriteLine("Coordonatele celui de-al treilea punct:").ToDouble(System. sunt coliniare.ToDouble(System.

x. x = Convert. } // interschimbarea valorilor pentru a avea intervalul [a. {2} ]". a. b = x.ReadLine()).Exemplul 25: Să se verifice dacă un număr întreg x este într-un interval dat [a. Console.ToInt32(Console. a = Convert. namespace Exemplul_25 { class Program { static void Main(string[] args) { int a. {2} ]". x.Write("Dati a doua valoare : ").Linq.ReadLine()). System.Collections.Write("Dati prima valoare : "). b] using using using using System.ToInt32(Console. if (a > b) { x = a. System. System. a.Generic. b.WriteLine("Se citesc doua numere care vor reprezenta capetele intervalului").Write("x = ").WriteLine("Numarul {0} nu este in intervalul [ {1}. Console.ReadLine()). Console. a = b. } } } 32 . x.Text. b).ToInt32(Console. b = Convert. b] Console. else Console. if (x >= a && x <= b) Console. b).WriteLine("Numarul {0} este in intervalul [ {1}.

ux.ReadLine()). case 2: Console. case 1: Console. Console. break. break. x = Convert.WriteLine(" 6 "). System. n. Console.Write("Dati un numar natural ca exponent al puterii : "). using using using using System.I. System. dacă la finalul instrucţiunilor dintr-o ramură case nu există break. break. case 2: k = n % 4. 33 .2.Write("Dati un numar natural ca baza a puterii : "). else switch (ux) { case 0: Console. break. n). ux = x % 10.Text. switch (k) { case 0: Console.ToInt32(Console. System. Există şi aici posibilitatea de a face verificări multiple (în sensul de a trece la verificarea următoarei condiţii din case) doar dacă case-ul nu conţine instrucţiuni: Instrucţiunea switch admite în C# variabilă de tip şir de caractere care să fie comparată cu şirurile de caractere din case-uri: Exemplul 26: Programul următor afişează ultima cifră a numărului xn. case 3: Console. case 1: Console. n = Convert. break.Linq. În C# se semnalează eroare. se trece la următorul case.2. x.Collections.WriteLine(" 2 ").WriteLine(" 4 ").WriteLine(" 8 ").6. namespace Exemplul_26 { class Program { static void Main(string[] args) { int x. } break.WriteLine(" 1 ").WriteLine(" 1 ").WriteLine(" 0 "). unde x şi n sunt numere naturale citite de la tastatură. if (n == 0) Console.ToInt32(Console. k.ReadLine()). break. Instrucţiunea switch În cazul instrucţiunii switch în C/C++. // ma intereseaza doar ultima cifra Console.Write("Ultima cifra a lui {0} la puterea {1} este : ".Generic.

case 3: k = n % 4; switch (k) { case 0: Console.WriteLine(" 1 "); case 1: Console.WriteLine(" 3 "); case 2: Console.WriteLine(" 9 "); case 3: Console.WriteLine(" 7 "); } break; case 4: if (n % 2 == 0) Console.WriteLine(" 6 else Console.WriteLine(" 4 "); break; case 5: Console.WriteLine(" 5 "); break; case 6: Console.WriteLine(" 6 "); break; case 7: k = n % 4; switch (k) { case 0: Console.WriteLine(" 1 "); case 1: Console.WriteLine(" 7 "); case 2: Console.WriteLine(" 9 "); case 3: Console.WriteLine(" 3 "); } break; case 8: k = n % 4; switch (k) { case 0: Console.WriteLine(" 6 "); case 1: Console.WriteLine(" 8 "); case 2: Console.WriteLine(" 4 "); case 3: Console.WriteLine(" 2 "); } break; case 9: if (n % 2 == 0) Console.WriteLine(" 1 else Console.WriteLine(" 9 "); break; } } } using using using using } System; System.Collections.Generic; System.Linq; System.Text;

break; break; break; break;

");

break; break; break; break;

break; break; break; break;

");

34

Exemplul 27: Programul următor efectuează calculele corespunzătoare pentru două numere întregi şi unul dintre semnele +,-,*,/ , % introduse de la tastatură

namespace Exemplul_27 { class Program { static void Main(string[] args) { char op; int a, b; Console.WriteLine("Exemplu pentru operatori aritmetici"); Console.Write("Dati primul numar intreg : "); a = Convert.ToInt32(Console.ReadLine()); Console.Write("Dati al doilea numar intreg : "); b = Convert.ToInt32(Console.ReadLine()); Console.Write("Dati simbolul unui operator aritmetic : "); op = (char)Console.Read(); switch (op) { case '+': Console.WriteLine("Adunare : {0} + {1} = {2}", a, b, a + b); break; case '-': Console.WriteLine("Scadere : {0} - {1} = {2}", a, b, a - b); break; case '*': Console.WriteLine("Inmultire : {0} * {1} = {2}", a, b, a * b); break; case '/': Console.WriteLine("Impartire : {0} / {1} = {2}", a, b, (float)a / b); break; case '%': Console.WriteLine("Modulo : {0} % {1} = {2}", a, b, a % b); break; default: Console.WriteLine("Simbolul nu reprezinta o operatie aritmetica"); break; } } } }

35

I.2.6.2. Instrucţiunea while
Instrucţiunea while are sintaxa: while (conditie) Instructiuni;

Cât timp conditie este îndeplinită se execută Instructiuni.

Exemplul 28: Să se afişeze numerele întregi pozitive <= 10

using System; namespace Exemplul_28 { class Program { static void Main(string[] args) { int n = 0; while (n <= 10) { Console.Write("{0,3}", n); n++; } Console.ReadLine(); } } }

36

Exemplul 29: Programul de mai jos numără câte cifre pare are un număr natural:
using System; namespace Exemplul_29 { class Program { static void Main(string[] args) { uint a = 1223466, b; b = CateCifrePare(a); Console.WriteLine("Numarul {0} are {1} cifre pare", a, b); } static uint CateCifrePare(uint a) { uint k = 0; if (a == 0) k = 1; while (a != 0) { if (a % 10 % 2 == 0) k++; // sau if(a % 2 == 0) // pentru ca a numar par daca si numai daca ultima cifra este para a = a / 10; } return k; } } }

Exemplul 30: Să se calculeze cmmdc şi cmmmc pentru două numere citite de la tastatură.
using using using using System; System.Collections.Generic; System.Linq; System.Text;

namespace Exemplul_30 { class Program { static void Main(string[] args) { int a, b, r, x, y; Console.Write("Dati primul numar : "); a = Convert.ToInt32(Console.ReadLine());

37

System.WriteLine("Cmmdc ({0}. Console.WriteLine("Cmmmc ({0}.Write("Dati al doilea numar : "). } } } Exemplul 31: Dintr-un număr întreg pozitiv. namespace Exemplul_31 { class Program { static void Main(string[] args) { uint n. System. y). r = x % y. min. while (r != 0) { x = y. b. a / y * b). a. Console. } if (y != 1) Console. Console.WriteLine("{0} si {1} sunt prime intre ele ". n. {1}) = {2} ".ReadLine()). min = MinCifra(n). v.Linq.Console.Generic.Text. else Console.ToInt32(Console. b). v). a. } 38 . y = b. b = Convert. x = a. System. {1}) = {2}". using using using using System. a.ReadKey().ReadLine()). y = r. b. r = x % y.ToUInt32(Console. min).Collections.WriteLine("Eliminand cifra minima {0} din {1} obtinem {2}". v = Valoare(n. citit de la tastatură. să se elimine cifra cea mai mică şi să se afişeze numărul rezultat în urma acestei operaţii. n = Convert.Write("Dati un numar intreg pozitiv : "). Console. min.

uint min) { uint y = 0. while(conditie) Se execută Instructiuni după care se verifică conditie. p *= 10. while (x != 0) { if (x % 10 < min) min = x % 10. Dacă aceasta este adevărată. p = 1.2. x /= 10. } x /= 10. } return y. altfel ciclul se termină. } static uint Valoare(uint x. 39 .4.6. } } } I.static uint MinCifra(uint x) { uint min = 9. ciclul se reia. Instrucţiunea do – while Instrucţiunea do – while are sintaxa: do Instructiuni. } return min. while (x != 0) { if (x % 10 != min) { y = y + (x % 10) * p.

Generic. do { Console.ReadLine().Write("{0. n).Linq.Write("Numerele palindroame mai mici strict decat {0} sunt :\n". namespace Exemplul_32 { class Program { static void Main(string[] args) { int n = 0.ToInt32(Console. n++. using using using using System. namespace Exemplul_33 { class Program { static void Main(string[] args) { int x.Text. să se afişeze şi numărul lor.Exemplul 32: Asemănător cu exerciţiul 28. n. k = 0. până la o valoare citită de la tastatură. Console. System. System. 40 .Write("Dati un numar natural : "). să se afişeze numerele întregi pozitive <= 10 using System. De asemenea. } } } Exemplul 33: Să se afişeze numerele cu proprietatea de a fi palindroame.WriteLine("Eroare la citire!"). System. n = Convert.Collections. n). } while (n <= 10) . x = 1. do { Console. } while (n <= 0). Console.3}". if (n <= 0) Console.ReadLine()).

else Console. } x++. if (y == x) return 1.3} ".WriteLine(). } while (z != 0).2. conditieFinal. I.5. } } } if (palindrom(x) == 1) { Console.6. k). else return 0. z = x. k++.WriteLine("Sunt {0} numere palindroame!". z /= 10. } while (x < n). do { y = y * 10 + z % 10.do { } static uint palindrom(int x) { int y = 0.Write(" {0. Instrucţiunea for Instrucţiunea for are sintaxa: for(initializareCiclu. reinitializareCiclu) Instructiune 41 .WriteLine("Nu exista numere!"). Console. if (k == 0) Console. x).

n).ReadLine()). } } } Exemplul 35: Să se determine numerele prime. k = 0. namespace Exemplul_35 { class Program { static void Main(string[] args) { int a. // k va determina cate numere prime sunt in interval do { Console. System.Exemplul 34: Ne propunem. } Console.Write("Dati a doua valoare : ").Collections. } while (b <= a).Text.Write("{0. b = Convert. System. x. 42 . b. using using using using System. n <= 10. cuprinse între două valori întregi citite de la tastatură.Linq.Write("Dati prima valoare : ").ToInt32(Console. n++) { Console. do { Console.ReadLine()). namespace Exemplul_34 {class Program {static void Main(string[] args) { for (int n = 0. să afişăm numerele pozitive <=10 using System. a = Convert. } while (a <= 0).Generic. System.3}". precum şi numărul lor.ReadLine().ToInt32(Console.

Generic. } } } Exemplul 36: Un exemplu de for pe numere reale. b. d += 2) if (x % d == 0) return 0. return 1. k++.4. namespace Exemplul_36 { class Program { static void Main(string[] args) { double rc. double x. for (x = a. x <= b. ic -= 0.80. y.05) { for (rc = -0. x++) if (prim(x) == 1) { Console.7.WriteLine("In intervalul [ {0}. for (int d = 3. int n. x). System. System. System. k). b). rc += 0. ic. z. {1} ] sunt {2} numere prime!". {1} ] nu sunt numere prime!". a.Linq. ic >= -1. d * d <= x. if (k == 0) Console.Collections.Write("{0. 3}".WriteLine(). if (x % 2 == 0 && x != 2) return 0. for (ic = 1. } static int prim(int x) { if (x == 1) return 0.05) { 43 .Console. a. } Console. else Console.Text.Write("Numerele prime : "). rc <= 1.WriteLine("In intervalul [ {0}.4. using using using using System.

while (n <= 40 && z < 5) { x = ic * ic + rc * rc .Write("*").4 * rc. break. x = ic * ic + rc * rc. n++.Write("$").4 * rc. case 3: Console. z = x * x .WriteLine(). y = 2 * ic . break. 44 . case 2: Console.rc.y * y. } switch (n % 4) { case 0: Console. y = 2 * ic . case 1: Console. break. z = x * x + y * y.Write("@").Write("o"). n = 0.} } } } } Console. } break.

neputând fi transmis ca parametru şi nici aplicat un operator care să-i schimbe valoarea. executând o instrucţiune pentru fiecare element.2. 45 . Instrucţiunea foreach O instrucţiune nouă. Această instrucţiune enumeră elementele dintr-o colecţie. Elementul care se extrage este de tip read-only. pe care o aduce limbajul C#. este foreach.I.6.6.

'. "Ionel".Write("{0} ".Length. o vom compara cu instrucţiunea cunoscută for.WriteLine("Sirul care va fi impartit in cuvinte \n‘{0}’".Length). i<nume. char[] delimitator = { ' '. } } } } 46 . foreach(char c in s) Console. Exemplul 37: Să se împartă un şir de caractere în cuvinte. string[] cuvant = sir.Pentru a vedea cum acţionează. Console. Se va afişa numărul de cuvinte şi fiecare cuvânt în parte using System. sir). Console. foreach (string s in cuvant) { Console.Write(c). i++) Console. "Maria"} Afişarea şirului folosind for: for(int i=0.Write("{0} ".Split(delimitator). '. namespace Exemplul_37 { class Program { static void Main(string[] args) { string sir = "Acesta este un sir". nume[i]). Considerăm un vector nume format din şiruri de caractere: string[] nume = {"Ana". Acelaşi rezultat îl obţinem folosind instrucţiunea foreach: foreach (string copil in nume) Console.WriteLine(s).WriteLine("Sunt {0} cuvinte in text:". ':' }. '.'. Mai dăm încă un exemplu de folosire a lui foreach: string s="Curs"+" de"+" informatica". cuvant. copil).

în C#. y = 8.I. goto default. while. y = 0. pentru efectuarea unor salturi.6.2. for sau foreach. case 15: x = 3. y = 1. în instrucţiunea switch Exemplul 38: switch (a) { case 13: x = 0. 47 . break. Instrucţiunea continue Instrucţiunea continue permite reluarea iteraţiei celei mai apropiate instrucţiuni switch. } I. y = 0.6. default: x = 1. break.8. goto case 20. Instrucţiunea goto Instrucţiunea goto poate fi folosită. do – while. case 20: x = 5.2.7.

Pot exista mai multe blocuri catch. namespace Exemlul_39 { class Program { static void Main(string[] args) { int i = 0. else break. while (true) { Console. Exemple: erori la deschiderea unor fişiere a căror nume este greşit. Ea se foloseşte pentru a semnala contextul în care apare o situaţie specială. se va „arunca” o excepţie care trebuie sesizată şi tratată. fiecare dintre ele prinde şi tratează o excepţie. Aruncarea excepţiilor se face cu instrucţiunea throw throw new System.6. i++. Aceste erori se pot manipula astfel încât programul să nu se prăbuşească.Exemplul 39: using System.Write("{0} ".2. Prinderea şi tratarea excepţiilor se face folosind un bloc catch.ReadLine().9. 48 .Exception sau derivate ale acestuia. i). if (i < 10) continue. Când o metodă întâlneşte o situaţie dintre cele menţionate mai sus. } } } I.Exception(). } Console. Instrucţiunile try-catch-finally şi throw Prin excepţie se înţelege un obiect care încapsulează informaţii despre situaţii anormale. Limbajul C# poate arunca ca excepţii obiecte de tip System. împărţire la 0 etc.

txt” using System.OpenRead("Gigel.txt"). Exemplul 40: Presupunem că dorim să citim fişierul „Gigel. using System. vom prinde excepţia. acest cod se va pune în blocul finally care se va executa în orice situaţie. Putem vizualiza mesajul produs de excepţia întâlnită: 49 .Pentru a garanta că un anumit cod se va executa indiferent dacă totul decurge normal sau apare o excepţie.IO. } } } Încercând să compilăm obţinem: Pentru a remedia această eroare. namespace Exemplul_40 { class tryCatch { static void Main(string[] args) { File. punând într-un bloc try linia care a furnizat-o.

namespace Exemplul_40 { class tryCatch { static void Main(string[] args) { try { File.ReadLine().OpenRead("Gigel. } finally { Console.txt"). using System.WriteLine(a). } } } } Bineînţeles că în blocul catch putem să scriem ce cod dorim.using System.WriteLine("Acest bloc se va executa").IO. } catch (FileNotFoundException a) { Console. de exemplu: 50 . Console.

Exception şi derivate ale acesteia servesc la tratarea adecvată şi diversificată a excepţiilor.txt"). namespace Exemplul_40 { class tryCatch { static void Main(string[] args) { try { File. „aruncând” o excepţie (instrucţiunea throw) sau putem profita de mecanismul de tratare a erorilor pentru a implementa un mecanism de validare a datelor prin generarea unei excepţii proprii pe care. } } } } Alteori putem simula prin program o stare de eroare.WriteLine("Nu exista fisierul cerut de dv. Clasa System. using System.OpenRead("Gigel. } catch (FileNotFoundException a) { Console.WriteLine("Acest bloc se va executa"). o „aruncăm” în momentul neîndeplinirii unor condiţii puse asupra datelor.using System. 51 .ReadLine()."). Console. de asemenea. } finally { Console.IO.

sau int[] v = {1.7.Write("{0. se creează o instanţă a clasei .NET. Se pot face în acelaşi timp operaţiile de declarare. Pentru aceasta. 6 }. System. 4.7. i++) Console. apelând metode ale System. Tablouri I.Write("{0. 2. i < v. //sortarea crescatoare a vectorului v for (int i = 0.Array. Compilatorul va traduce operaţiile asupra tablourilor. Exemplul 41: Crearea. instanţiere şi iniţializare: Exemplu: int[] v = new int[] {1. //afisarea vectorului v Afişarea se poate face şi cu ajutorul lui foreach: foreach (int i in v) Console. Prin această declaraţie nu se alocă şi spaţiu pentru memorare. 8.Array. C/C++). Array. v[i]). 52 .2.3).Length. sortarea şi afişarea unui vector: int[] v = new int[5] { 10.2.3}".1.3}". La declararea unui tablou. Declararea unui tablou unidimensional se face astfel: Tip[] nume.Sort(v).3). Tablouri unidimensionale  Limbajul C# tratează tablourile într-o manieră nouă faţă de alte limbaje (Pascal.i). tabloul trebuie instanţiat: nume = new Tip[NumarElemente].2.2.I.

3 }.2. i++) { q[0] = 1. for (i = 1.Exemplul 42: Să se afişeze numărul de elemente de pe a doua linie a tabloului şi numărul total de linii. j <= i . int[] p. j++) { Console. namespace Exemplul_43 { class Program { static void Main() { int n. 2.Write(q[j] + " ").1.GetLength(1)).WriteLine(tab. for (j = 1. q.ReadLine()). j <= i . q = new int[n + 1]. namespace Exemplul_42 { class Program {static void Main(string[] args) { int[. n = Convert. // Reamintim ca prima linie are numarul de ordine 0 Console. 5. } Console. Console. j.ReadLine(). using System. j++) q[j] = p[j .1] = 1.] tab = { { 1. p[j] = q[j]. q[i . 6 } }.WriteLine().1] + p[j]. using System.Rank). } } } Exemplul 43: Să se afişeze primele n+1 linii din triunghiul lui PASCAL(n≤20). // Afisarea numarului de linii a tabloului tab Console.WriteLine(tab. p[0] = 1. for (j = 0. // Afisarea numarului de elemente ale // lui tab de pe linia a 2-a.ToInt32(Console. { 4. } } } } 53 . i. p = new int[n + 1]. i <= n + 1.

namespace Exemplul_44 { class Program { static void Main() { int n. k. Pentru un număr natural n dat se afişează toate numerele prime mai mici decât n. i <= n. j. i. …. } } } 54 . n = Convert. 4.ToInt32(Console. Pentru a obţine acest şir „tăiem” mai întâi toţi multiplii lui 2. În final rămân numai numerele prime din intervalul [2. Console. i = 2.n]. for (i = 2.a. using System.Write(c[i] + " "). atribuirea valorii zero pentru acel element. apoi ai lui 3 ş. int[] c. j += i. i++) if (c[i] != 0) Console. i++) c[i] = i. Selectarea numerelor prime se face folosind ciurul lui Eratostene Ciurul lui Eratostene presupune formarea unui şir din numerele 2. 3.WriteLine(). n-1. n. while (i <= n / 2)//cel mai mare divizor propriu al unui numar este<=jumatatea sa { if (c[i] != 0) { j = 2 * i.ReadLine()). while (j <= n) { if (c[j] != 0) c[j] = 0.Exemplul 44: Ciurul lui Eratostene. c = new int[n + 1]. } } i++. Noţiunea de „tăiere” a unui element va însemna. } for (i = 2.d. în acest caz.m. i <= n.

int[] f. n = Convert.ReadLine()). i++) f[i] = f[i . i. i <= n. f = new int[n + 1].Write("Numarul de trepte = "). namespace Exemplul_45 { class Program { static void Main() { int n.1] + f[i . În câte moduri poate urca Ionel cele n trepte? Dacă notăm cu f[i] numărul de moduri în care poate urca copilul i trepte.ToString()). using System. } } } 55 . f[1] = f[2] = 1. El poate urca păşind pe treapta următoare sau sărind peste o treaptă.ToInt32(Console. Pentru a determina numărul de moduri.WriteLine("Numarul de posibilitati este = {0}".Exemplul 45: Ionel urcă în fiecare zi n trepte(n<40) până la apartamentul în care locuieşte. Console.2]. Console. Console. observăm că există 2 moduri prin care acesta poate ajunge la treapta i: de la treapta i-1 sau de la treapta i-2.ReadLine(). vom însuma în câte moduri poate ajunge pe treapta i-1 cu numărul de modalităţi de a ajunge pe treapta i-2. for (i = 3.f[n]. deci f[i]=f[i-1]+f[i-2].

f). Console. } else if (a[i] == max) f++. i++) { Console. max. i < n. i. int[] a. } } } 56 .Exemplul 46: Să se determine valoare elementului maxim dintr-un tablou unidimensional. a[i] = Convert. max. for (i = 1.Write(" a[ {0} ] = ".ReadLine()). i + 1). n = Convert. f = 1. } max = a[0].Write("Dati dimensiunea tabloului : "). Console. precum şi frecvenţa sa de apariţie using System. i < n.WriteLine("Maximul din tablou este {0} cu frecventa {1} ". namespace Exemplul_46 { class Program { static void Main(string[] args) { int n. i++) if (a[i] > max) { max = a[i].ToInt32(Console.ReadLine()). a = new int[n + 1]. for (i = 0.ToInt32(Console. f = 1. f.

ReadLine()). a[i + 1] = putere(a[i]). Console.WriteLine("Afisare tablou dupa inserare puteri ale lui 2 : "). i < n. int[] a. i + 1). i++) Console. n++. } 57 .Exemplul 47: Operaţii cu elementele unui vector: citire. eliminare elemente de valoare 0. i += 2) { for (j = n.ReadLine()). inserare după fiecare valoare a celei mai apropiate puteri ale lui 2 (dacă cele două puteri sunt la aceeaşi distanţă faţă de număr se va insera cea mai mică dintre cele doua puteri) using System.Write("{0} ". i < n.Write("{0} ".WriteLine(). for (i = 0. i. for (i = 0.1].Write("{0} ". j. a[i]). i < n. Console. Console. i++) Console. while (a[i] != 0 && i < n) i++. // stergere valori nule i = 0. j--) a[j] = a[j . j < n && a[j] == 0. // inserare valori for (i = 0. Console. n = Convert. } Console. a[i]).WriteLine("Afisare tablou fara valori nule : "). Console. for (i = 0.WriteLine("Afisare tablou : "). } Console. i < n.WriteLine(). a[i++] = a[j].Write("Dati dimensiunea tabloului : "). afişare. a[i]).ToInt32(Console. j++) .Write(" a[ {0} ] = ". namespace Exemplul_47 { class Program { static void Main(string[] args) { int n. k = 0. Console. i++) { Console. for (i = 0.WriteLine(). k++. while (i < n) { if (a[i] == 0) { for (j = i.WriteLine("Citire tablou : "). i < n.1] == 0 && n > 0) n--.ToInt32(Console. a[i] = Convert. j > i. a = new int[2 * n + 1]. a[j] = 0. i++) Console. } while (a[n . } else i++.

else return p.2.x) return q. } } } I.q <= p . if (x . q = p / 2. q. iar instanţierea: nume = new Tip[Linii.static int putere(int x) { int p = 1. Accesul: nume[indice1. while (p <= x) p *= 2.] nume. Tablouri multidimensionale În cazul tablourilor cu mai multe dimensiuni facem distincţie între tablouri regulate şi tablouri neregulate (tablouri de tablouri) Declararea în cazul tablourilor regulate bidimensionale se face astfel: Tip[.2.7.Coloane].indice2] 58 .

sau Tip [][] nume = { new Tip[] {sir_0}. new Tip[] {sir_n} }.{7.{4.. //tablou neregulat cu doua //dimensiuni iar instanţierea şi iniţializarea: Tip [][] nume = new Tip[][] { new Tip[] {sir_0}.8. new Tip[] {sir_n} }.5.. Acces nume[indice1][indice2] 59 .3}. new Tip[] {sir_1}.2. În cazul tablourilor neregulate (jagged array) declararea se face: Tip [][] nume.] mat = new int[.{7.] mat = {{1.6}.6}. .8..9}}.{4. new Tip[] {sir_1}. sau int[.Exemplu: Declararea instanţierea şi iniţializarea int[.2..9}}.5.3}.] {{1. .

new int[4] { 7. Se citeşte un număr natural n. . 5 }. atunci rezultă că există i.] vect = new int[6. Vectorii 3-D sunt utilizaţi frecvent în aplicaţiile grafice. new int[2] {4.kN* astfel încât i+(i+1)+(i+2)+(i+3)+……+(k)=n ↔ (1+2+..1} }. 9. Să se memoreze toate posibilităţile de descompunere a numărului n în sumă de numere consecutive. Dacă numărul n se scrie ca sumă de numere naturale consecutive. 2.5}.3}..2. new int[3] { 1. 60 .] vect = new int[2. 2. 4. Exemple: int[. int[. 8.Exemple: int[][] mat = new int[][] { new int[3] {1.9.+i-1)=n↔k*(k+1)/2-i*(i-1)/2=n ↔k2+k-i2+i-2n=0 ↔k=(-1+ 1  8n . . sau int[][] mat = { }. new int[2] { 4. Exemplul 48: Descompunerea unui număr în sumă de numere naturale consecutive.4i  4i 2 )/2 Vom memora descompunerile în matricea neregulată a (descompunerile au dimensiuni variabile). 3 }. 8].+k)-(1+2+. ..8. 5].. 1 } Observaţie: Este posibilă declararea vectorilor de dimensiuni mai mari. new int[4] {7. 3.

4 * i + 4 * i * i) . namespace Exemplul_48 { class Program { static void Main() { Console.WriteLine(). i.1)/ 2.Length. j++) Console. să se determine:   maximul dintre valorile situate deasupra diagonalei principale numărul de numere prime (dacă acestea există) situate sub diagonala secundară 61 . ale cărei elemente întregi se citesc de la tastatură. if (k == (int)k) { a[l] = new int[(int)k . int[][] a = new int[n / 2][].ToInt32(Console. n). } } } } Exemplul_49: Pentru o matrice pătratică. i <= n / 2. } } Console. l++.Sqrt(1 + 8 * n . i < l. int l = 0. j. j <= k. Console. j++) a[l][j . for (j = i. for (i = 0.Write(a[i][j] + " ").i + 1]. for (i = 1. j < a[i].ReadLine()). int n = Convert.WriteLine("Descompunerea lui {0} in suma de numere naturale consecutive".Write("Introduceti un numar natural "). i++) { double k = (Math.using System.i] = j. i++) { for (j = 0.

] a. j < n.Write("{0. d * d <= x. n. int k = 0. j < n. } Console.ReadLine()). j + 1). Console. j] > max) max = a[i. n + 1]. j].Collections. a[i. j++) Console. using System. i + 1. a[i. for (i = 0. j]) == 1) k++.Text. for (i = 1. int[. j++) if (a[i.ReadLine()). d += 2) if (x % d == 0) return 0.WriteLine("Maximul dintre valorile situate deasupra diagonalei principale : {0}".WriteLine("Sub diagonala secundara sunt {0} numere prime!". using System. j. else Console. j] = Convert. i < n . a = new int[n + 1. i++) { for (j = 0. j]). Console. Console.WriteLine("Afisare matrice : "). for (int d = 3.ToInt32(Console.Write("Dati dimensiunea matricei patratice : ").WriteLine(). if (k == 0) Console.WriteLine("Citire matrice : ").i. return 1. i++) for (j = 0. } } } 62 . for (i = 0. i < n. } static int prim(int x) { if (x == 1) return 0. i < n. j++) if (prim(a[i.WriteLine("Sub diagonala secundara nu sunt numere prime!"). j < n. 4}". max). i < n. j < n.ToInt32(Console. for (i = 0. n = Convert.Write("a[{0}][{1}] = ". namespace Exemplul_49 { class Program { static void Main(string[] args) { int i. j++) { Console. i++) for (j = n . } int max = a[0.using System. if (x % 2 == 0 && x != 2) return 0.Generic. 1]. k). Console.1. i++) for (j = i + 1.

63 .8. în limbajul C#. string a = "Acesta este un sir de caractere".String (sau aliasul string). inclusiv secvenţe escape. tipul de date utilizat este clasa System. string b = "". Şiruri de caractere Pentru reprezentarea şirurilor de caractere. string nume = "Gigel".2.I. Se definesc două tipuri de şiruri:   regulate de tip „Verbatim” Tipul regulat conţine între ghilimele zero sau mai multe caractere.

string c = @"linia unu linia doi". la regiştri. Aceste şiruri se folosesc în special în cazul în care dorim să facem referiri la fişiere.ReadLine(). string e = @"c:\exemple\unu. } } } Secvenţele escape permit reprezentarea caracterelor care nu au reprezentare grafică precum şi reprezentarea unor caractere speciale: backslash. Console. Console. string d = "c:\\exemple\\unu. pe lângă şirurile regulate şi cele de tip verbatim.cs". putem utiliza şirurile verbatim.WriteLine(a). Un astfel de şir începe cu simbolul „@” înaintea ghilimelelor de început. la prelucrarea lor. Console. Secvenţă escape \’ \” \\ \0 \a \b \f \n \r Efect apostrof ghilimele backslash null alarmă backspace form feed – pagină nouă new line – linie nouă carriage return – început de rând 64 . În cazul în care folosim multe secvenţe escape. caracterul apostrof.WriteLine(c). Console.WriteLine(e). string b = "linia unu \nlinia doi".cs". etc. Exemplu: using System. Console.Limbajul C# introduce.WriteLine(d). namespace SiruriDeCaractere { class Program { static void Main(string[] args) { string a = "un sir de caractere". Console.WriteLine(b).

(object)a == b). Definiţie: două şiruri se consideră egale dacă sunt amândouă null. Compararea şirurilor de caractere Pentru a compara două şiruri de caractere vom utiliza operatorii “==” şi “!=”. sau dacă amândouă au aceeaşi lungime şi pe fiecare poziţie au caractere respectiv identice.Linq. } } } 65 . b). string b = "Invat " + "limbajul ".2.\t \u \v \x horizontal tab – tab orizontal caracter unicode vertical tab – tab vertical caracter hexazecimal I. Console.2. System.8.Collections. Console. Console. System.WriteLine("b='{0}'". Exemplul 50: Exemplul următor demonstrază că operatorul “==” este definit pentru a compara valoarea obiectelor string şi nu referinţa lor using using using using System.WriteLine("a == b {0}". System.WriteLine("(object)a == b {0}".8.1. namespace Exemplul_50 { class Program { static void Main(string[] args) { string a = "Invat limbajul C#". a == b). În caz contrar şirurile se consideră diferite. b += "C#". a).2.Generic. //a este "Invat limbajul C#" 1.Text.WriteLine("a='{0}'". Concatenarea şirurilor de caractere Pentru a concatena şiruri de caractere folosim operatorul “+” Exemplu: string a = "Invat " + "limbajul " + "C#". Console.

Funcţii importante pentru şiruri Clasa String pune la dispoziţia utilizatorului mai multe metode şi proprietăţi care permit prelucrarea şirurilor de caractere.2.I.8. Dintre acestea amintim: metode de comparare:   Compare CompareOrdinal CompareTo EndsWith StartsWith IndexOf LastIndexOf Concat CopyTo Insert Join PadLeft PadRight Remove Replace Split Substring ToLower ToUpper Trim TrimEnd TrimStart metode pentru căutare: -  metode care permit modificarea şirului curent prin obţinerea unui nou şir: - Proprietatea Length am folosit-o pe parcursul acestei lucrări şi. după cum ştim returnează un întreg care reprezintă lungimea (numărul de caractere) şirului. 66 .1.

WriteLine("b = '{0}'". string b = "C#". System. string v) string Split(char[] c) string Substring(int index) string Substring(int a. a).Linq.Collections. începând de pe poziţia a.WriteLine("a = '{0}'". Console. pe lungimea b caractere returnează un nou şir obţinut din cel iniţial prin convertirea tuturor caracterelor la minuscule returnează un nou şir obţinut din cel iniţial prin convertirea tuturor caracterelor la majuscule returnează un nou şir obţinut din cel iniţial prin ştergerea spaţiilor goale de la începutul şi sfârşitul şirului ini ial returnează un nou şir obţinut din cel iniţial prin ştergerea spaţiilor goale de la sfârşitul şirului ini ial returnează un nou şir obţinut din cel iniţial prin ştergerea spaţiilor goale de la începutul şirului ini ial Exemplul 51: Exemplificăm aplicarea funcţiilor de mai sus: using using using using System. int b) string Replace(string u. System. namespace Exemplul_51 { class Program { static void Main(string[] args) { string a = "Invat limbajul ". pe o lungime de b caractere returnează un nou şir obţinut din cel iniţial prin prin înlocuirea subşirului u cu şirul v împarte un şir în funcţie de delimitatorii c returnează un nou şir care este un subşir al şirului ini ial începând cu indicele index returnează un nou şir care este un subşir al şirului iniţial. string s) string Remove(int a. string c. 67 . b). string v) int IndexOf(char c) int IndexOf(string s) string Insert(int a. int b) string ToLower() string ToUpper() string Trim() string TrimEnd() string TrimStart() Descrierea returnează un nou şir obţinut prin concatenarea şirurilor u şi v returnează indicele primei apariţii a caracterului c în şir returnează indicele primei apariţii a subşirului s returnează un nou şir obţinut din cel iniţial prin inserarea în şirul iniţial. Console.Generic. a şirului s returnează un nou şir obţinut din cel iniţial prin eliminarea.Text.Tabelul de mai jos prezintă câteva dintre funcţiile (metodele) clasei String Funcţia (metodă a clasei Strig) string Concat(string u. System. începând cu poziţia a. începând cu poziţia a.

a. Console. } } } Exemplul 52: Programul următor contorizează majusculele dintr-un text.ToUpper()).WriteLine("a.WriteLine("d. Console.IndexOf(\"mba\") = {0}". Convert.ToString(a.WriteLine("a.Console. Console.WriteLine("a.Replace("limbajul ". Console.IndexOf("v"))). ".WriteLine("d. Console. namespace Exemplul_52 { class Majuscule { static void Main() { int i.Substring(10. 7)). Console.TrimStart()).")). using System. Convert.c = string. using System.Concat(a.ToLower() = {0}".WriteLine("d = {0}".Generic. 7) = {0}".Substring(6) = {0}". \"la informatica.WriteLine("a.Remove(5.Substring(6)). Console.Substring(10. string d = " Ana are mere.WriteLine("a. a.ToString(a. using System. 68 .WriteLine("a. b) = \"{0}\"".Insert(6. nrm = 0.Trim()). 3)). a. a. 3) = {0}". a.WriteLine("a.Collections.WriteLine("a.Text.\") = {0}".Concat(a.ToLower()). "la informatica. b).WriteLine("a. Console.ToUpper() = {0}". string text = System. d.IndexOf("mba"))).ReadLine(). Console. d). Console. d. Console.Insert(6.TrimStart() = {0}". Console. "de zor ")). a.IndexOf(\"v\") = {0}". a. c).Trim() = {0}".Replace(\"limbajul \".Remove(5. \"de zor \") = {0}".WriteLine("string. Console.

i < s1. } System. Ex : acum şi elev au aceeaşi textură (vocală consoană vocală consoană) using System. if (s1. } if (textura) Console. s1[i]) && strchr(v.} } } for (i = 0.Copy("aeiouAEIOU").ReadLine().WriteLine("Nu au aceeasi textura"). i < text. } static void Main() { String s1 = Console. s2[i]) || !strchr(v. i++) if (p[i] == p_2) return true.Length. s2[i])) textura = false. String s2 = Console. return false. else Console. char p_2) { for (int i = 0. else { for (i = 0. Nu se face distincţie între litere mari. namespace Exemplul_53 { class Program { private static bool strchr(string p. int i.ReadLine(). i++) { if (text[i] >= 'A' && text[i] <= 'Z') nrm++. } } } 69 .Length) textura = false. String v = string. litere mici.Console.Length != s2. Exemplul 53: Să se verifice dacă cuvintele s1 şi s2 citite de la tastatură au aceeaşi textură. Două cuvinte au aceeaşi textură dacă au aceeaşi lungime şi toate caracterele corespondente au acelaşi tip.WriteLine("numarul de majuscule este=" + nrm).WriteLine("Au aceeasi textura"). bool textura = true. s1[i]) && !strchr(v. i < p. i++) if (strchr(v.Length.Length.

} Console. char[] x = { ' '.' }.".'. Pentru aceasta se folosesc expresii regulate.Length. i++) { Console. 70 . '. lucru care ar fi de dorit. namespace Exemplul_54 { class Program { static void Main(string[] args) { String s = "Metoda Split() nu face gruparea mai multor separatori".nrcuv).'.Exemplul 54: Folosind metoda Split. nrcuv++. i < cuvant. '.Split(x). int nrcuv = 0. for (int i = 0. String[] cuvant = s. să se numere cuvintele unui text ştiind că acestea sunt separate printr-un singur separator din mulţimea { ' '. using System. '.WriteLine(cuvant[i]).'}.WriteLine("Textul contine {0} cuvinte. } } } Metoda Split() nu face gruparea mai multor separatori. '.

spatiu sau punct si virgula //unul sau mai multe.WriteLine(cuvant[i]).Length. .Text. //separator: virgula.]+"). Exemplul 55: using System. ınlocuiri pe text. i++) { Console. String[] cuvant = regex.ReadKey(). i < cuvant.Split(s). reprezinta o metoda extrem de facila de a opera cautari. } } } 71 . for (int i = 0. namespace Exemplul_55 { class Program { static void Main(string[] args) { String s = "Expresiile regulate . ". orice combinatie Regex regex = new Regex("[. } Console.Expresiile regulate reprezintă o metodă extrem de utilă pentru a opera căutări/înlocuiri pe text.RegularExpressions. using System.

namespace Exemplul_56 { class Program { static void Main(string[] args) { string[] a = { "primul". System.Text. Stocarea informaţiilor în fişiere I.9.2. Obiectul File este o reprezentare a unui fişier de pe disc. //deschiderea unui fisier si atasarea lui la un flux StreamWriter outputFile = File. I. Exemplul 56: using using using using System. "de mine".Collections.2. se ataşează unui flux un obiect File. Scrierea şi citirea datelor din fişiere text Fişierele de ieşire necesită utilizarea unui obiect StreamWriter. deschide un fişier şi creează obiectul StreamWriter. "fisier". StreamWriter. BinaryReader şi BinaryWriter. Aceste clase sunt folosite pentru operaţiile de intrare-ieşire cu fişiere. reprezintă administrarea fişierelor. System. Administrarea fişierelor Tehnica de citire şi scriere a datelor în şi din fişiere.I. "creat". 72 .9.txt"). În acest spaţiu există mai multe clase: File. }. utilizată pentru a păstra aceste informaţii.1.IO.CreateText("C:\\C#\\fisier1.2. Funcţia CreateText(). System. Limbajul C# oferă două tipuri de fişiere: fişiere text şi fişiere binare.IO. Pentru accesarea unui fişier de pe disc se folosesc funcţii din spaţiul de nume System. ce face parte din clasa File.Generic.2. iar pentru a-l utiliza trebuie să îl conectăm la un flux (stream). Astfel se face administrarea datelor. Pentru a scrie datele pe disc.9.

73 . pentru scrierea datelor programul creează un obiect FileStream.3. la care trebuie ataşat şi un obiect BinaryWriter.//scrierea textului in fisier } //inchiderea fisierului outputFile.WriteLine(x). //definim o variabila string care va parcurge fisierul pana la final string x. la cele binare.OpenText("C:\\C#\\fisier1. Scrierea şi citirea datelor din fişiere binare Dacă la fişierele text tipul de flux folosit era StreamWriter. } } } I.9.txt"). while ((x = inputFile.Close(). } //inchidem fisierul inputFile.WriteLine(b).Console. //deschidem din nou fisierul de data aceasta pentru a citi din el StreamReader inputFile = File.ReadLine()) != null) { System.foreach (string b in a) { outputFile.Close().2.

j <= 4.Generic. j] = 1.Close().dat". FileMode. j++) {//se apeleaza functia PeekChar care face parte din clasa BinaryReader //si examineaza urmatorul caracter din flux. for (i = 1. j. j <= 4.Open).Write("{0} ". g.Write("\n").Close(). daca acesta este diferit de -1 // atunci se executa citirea urmatorului caracter din flux prin functia ReadInt32() if (inputFile. x.dat". //se creeaza un fisier si un flux FileStream f = new FileStream("C:\\C#\\fisier2. j]). } } System. j++) if (i == j) a[i. //se inchide fisierul creat outputFile.ReadInt32(). x). bool final.Close(). namespace Exemplul_57 { class Program { static void Main(string[] args) { int i. //incepe citirea datelor din fisierul creat mai sus //se creeaza un obiect FileStream FileStream g = new FileStream("C:\\C#\\fisier2. j = 1.Console.] a = new int[10.PeekChar() != -1) { x = inputFile.i) a[i. i++) for (j = 1. i <= 4. !final. i = 1.Write(a[i. // se creeaza un scriitor binar si il ataseaza la flux //acesta traduce datele fluxului in format binar BinaryWriter outputFile = new BinaryWriter(f). j] = 2. System. using System. j] = 0.CreateNew). using System. else if (j == 5 . for (i = 1. } inputFile. else a[i.Exemplul 57: using System. using System. int[.Console. i++) for (j = 1. f. i++) { for (final = false. } } } 74 . 10]. for (final = false.Close().IO. i <= 4.Collections. !final. //se creeaza un obiect BinaryReader BinaryReader inputFile = new BinaryReader(g). j++) outputFile. FileMode.Text.

Principiile programării orientate pe obiecte I. păstrând vizibilitatea numai asupra zonei de interfaţă a modulului) şi se aplică tehnici de asociere a procedurilor cu datele pe care le manevrează. dorim să avem mai multe seturi diferite de date. toate înzestrate comportamental cu procedurile din modulul modul_1. Programarea modulară (gruparea subprogramelor cu funcţionalităţi similare în module. Programarea orientată obiect – POO (programe cu noi tipuri ce integrează atât datele. se obţin avantaje prin 75 . variabile locale şi apeluri cu parametri efectivi). această arhitectură de aplicaţie nu este avantajoasă. acestea gestionând şi setul de date pe care le prelucrează (date+date1 din figură). Evoluţia tehnicilor de programare Programarea nestructurată (un program simplu.1. implementate şi depanate separat). Programarea procedurală (program principal deservit de subprograme cu parametri formali.3. se obţin avantaje privind depanarea şi reutilizarea codului şi se aplică noi tehnici privind transferul parametrilor şi vizibilitatea variabilelor.I. complicaţiile apar atunci când la program sunt asignaţi doi sau mai mulţi programatori care nu pot lucra simultan pe un acelaşi fişier ce conţine codul sursă. prelucrării şi distrugerii acestor date). complicaţiile apar când prelucrarea devine mai amplă. cât şi metodele asociate creării. se obţin avantaje privind independenţa şi încapsularea (prin separarea zonei de implementare. program principal date modul_1 (date+date1)  subprog_1  subprog_2  subprog_3 modul_2 (date+date2)  subprog_1  subprog_2 Se observă că modulele sunt „centrate” pe proceduri. iar datele se multiplică şi se diversifică. stabilind şi diferite reguli de acces la date şi la subprograme. de exemplu. Dacă.3. ce utilizează numai variabile globale).

3. Încapsulare Definiţie: Un tip de date abstract (ADT) este o entitate caracterizată printr-o structură de date şi un ansamblu de operaţii aplicabile acestor date. vom observă că sunt multe date ce caracterizează un utilizator Internet. Definiţie: Numim instanţă a unui tip de date abstract o „concretizare” a tipului respectiv.). deoarece permite interacţiunea cu alte obiecte (SITE. Definiţie: Un tip de date obiectual este un tip de date care implementează un tip de date abstract. tipul abstract USER. derivarea şi polimorfismul tipurilor obiectuale. operaţii interne cum ar fi conversia datei de naştere la un număr standard calculat de la 01.2. ci un ansamblu de obiecte care prind obiect1  date1  met1 obiect4  date4  met4 obiect3 obiect2  date2  met2  date3  met3 viaţă. Definiţie: Operaţiile care sunt accesibile din afara ADT formează interfaţa acesteia. STOC etc. 76 . în timp ce operaţia „mănâncă” nu este. sunt capabile de acţiuni specifice şi care interacţionează în cadrul programului). intervin tehnici noi privind instanţierea. în cazul nostru. Evident. Astfel.abstractizarea programării (programul nu mai este o succesiune de prelucrări. „comandă on-line” pot fi relevante. au diverse proprietăţi. Tipuri de date obiectuale.01. nici nu se pun în discuţie date sau operaţii nespecifice („numărul de laturi” sau acţiunea „zboară”). În aceeaşi idee. Astfel. în timp ce „data naşterii” poate fi importantă. „culoarea ochilor” este irelevantă în acest caz.1900 nu fac parte din interfaţa tipului de date abstract. Considerând. I. în rezolvarea unei probleme de gestiune a accesului utilizatorilor la un anumit site. operaţii specifice ca „se înregistrează”. Totuşi se va ţine cont doar de datele semnificative pentru problema dată. în timp ce operaţia „plasează o comandă on-line” face parte. formată din valori efective ale datelor.

va muta valori dintr-o stivă în alta după o anumită regulă desfiinţând orice stivă golită. vom defini o structură de date care să reţină valorile memorate în stivă şi câmpuri de date simple pentru: capacitate. O instanţă a unui tip obiectual poartă numele de obiect. destructorul şi la metodele din interfaţa tipului STIVA descris mai sus. număr de elemente etc. Ea poate avea ca date: numerele naturale din stivă. de exemplu). Definiţie: Crearea unei instanţe noi a unui tip obiectual. va putea construi două sau mai multe stive (de cărţi de joc. capacitatea stivei.Definiţie: Vom numi metode operaţiile implementate în cadrul tipului de date abstract. Iar operaţiile specifice pot fi: introducerea în stivă (push) şi extragerea din stivă (pop). Există şi alte tipuri obiectuale (struct. se aplică o metodă specifică numită destructor (datorită tehnicii de supraîncărcare. să extragă valoarea din vârful stivei. astfel încât utilizatorul să nu fie nevoit să ţină cont de detalii ale acestei implementări. Definiţie: La desfiinţarea unei instanţe şi eliberarea spaţiului de memorie aferent datelor sale. La implementarea tipului STIVA. Vom mai defini metode (subprograme) capabile să creeze o stivă vidă. până ce rămâne o singură stivă. C#) poartă numele de clasă (class). O aplicaţie ce utilizează tipul obiectual STIVA. vârful etc. De observat că toate aceste prelucrări recurg la datele. presupune operaţii specifice de „construire” a noului obiect. Definiţii: Principalul tip obiectual întâlnit în majoritatea mediilor de dezvoltare (Visual Basic. le va umple cu valori distincte. object). Definiţie: La implementare. El 77 . constructorul. Exemplul 58: Un exemplu de-acum clasic de tip de date abstract este STIVA. Delphi. să testeze dacă stiva este vidă sau dacă stiva este plină etc. metoda corespunzătoare purtând numele de constructor. datele şi metodele asociate trebuie să fie complet şi corect definite. care să introducă o valoare în stivă. limbaje de genul C++. Definiţie: Numim membri ai unui tip de date obiectual datele şi metodele definite mai sus. C++. Java. Java şi C# permit existenţa mai multor constructori ). Folosirea unui tip de date obiectual tip presupune:    existenţa definiţiei acestuia apelul metodelor accesul la date.

Mai mult. clasele pot avea la implementare:   date şi metode caracteristice fiecărui obiect din clasă (membri de tip instanţă). programatorul ce utilizează un tip obiectual CONT (în bancă) nu trebuie să poarte grija modului cum sunt reprezentate în memorie datele referitoare la un cont sau a algoritmului prin care se realizează actualizarea soldului conform operaţiilor de depunere. membrii statici pot fi referiţi chiar şi fără a crea vreo instanţă a clasei respective. membrii statici sunt unici. Supraîncărcarea permite obţinerea unor efecte diferite ale apelului în contexte diferite Capacitatea unor limbaje (este şi cazul limbajului C#) de a folosi ca „nume” al unui subprogram un operator. prin intermediul metodelor puse la dispoziţie de tipul obiectual definit. extragere şi aplicare a dobânzilor. Aceasta este o facilitate care „reduce” 78 . Permiţând extensia tipurilor de date abstracte. prin intermediul proprietăţilor şi va efectua operaţiile. reprezintă supraîncărcarea operatorilor. ea creează un anumit context pentru metodele ce formează o clasă şi modul în care acestea pot fi (ca orice subprogram) apelate.va accesa datele.3. date şi metode specifice clasei (membri de tip clasă). Definiţie: Prin supraîncărcare se înţelege posibilitatea de a defini în acelaşi domeniu de vizibilitate mai multe funcţii cu acelaşi nume. Astfel. I. realizatorul tipului obiectual asumându-şi acele griji în momentul definirii tipului CONT. numărul maxim sau numărul minim de componente ale stivelor existente etc. Dacă în cazul membrilor nestatici. Spunem că tipurile de date obiectuale respectă principiul încapsulării. accesând proprietăţile şi metodele din interfaţă. dar cu parametri diferiţi ca tip şi/sau ca număr. nu unul de tip instanţă.3. fiind accesaţi în comun de toate instanţele clasei. Definiţie: Ansamblul format din numele funcţiei şi lista sa de parametri reprezintă o modalitate unică de identificare numită semnătură sau amprentă. EL va utiliza unul sau mai multe conturi (instanţe ale tipului CONT).Supraîncărcare Deşi nu este o tehnică specifică programării orientată obiect. în plus. clasa STIVA poate beneficia. Modificatorul static plasat la definirea unui membru al clasei face ca acela să fie un membru de clasă. există câte un exemplar al membrului respectiv pentru fiecare instanţă a clasei. şi de date ale clasei cum ar fi: numărul de stive generate. Astfel.

79 . Apelul unei funcţii care beneficiază. de două sau mai multe semnături se realizează prin selecţia funcţiei a cărei semnătură se potriveşte cel mai bine cu lista de parametri efectivi (de la apel). Astfel. poate fi definită metoda „comandă on-line” cu trei semnături diferite:  comanda_online(cod_prod) cu un parametru întreg (desemnând comanda unui singur produs identificat prin cod_prod comanda_online(cod_prod. o clasă abstractă trebuie obligatoriu derivată. aceeaşi superclasă însă poate fi derivată în mai multe subclase distincte. Definiţie: Ca şi în Java. Astfel. adică avem de-a face cu moştenire simplă.  În contextul mecanismelor de moştenire trebuie amintiţi modificatorii abstract şi sealed aplicaţi unei clase. cu această ocazie putând fi redefiniţi unii membri existenţi sau adăugaţi unii membri noi. toate clasele moştenesc de la clasa de bază Object. în C# o subclasă poate moşteni de la o singură superclasă. deoarece direct din ea nu se pot obţine obiecte prin operaţia de instanţiere. la rândul ei. prin supraîncărcare.3.calitate) cu primul parametru întreg şi al-II-lea caracter. Definiţii: Clasa din care se moşteneşte se mai numeşte clasă de bază sau superclasă.4. clasă derivată sau clasă descendentă. Operaţia mai poartă numele de derivare. în timp ce o clasă sigilată (sealed) nu mai poate fi derivată (e un fel de terminal în ierarhia claselor). prin supraîncărcarea operatorilor şi metodelor se pot crea şi confuzii. O clasă de bază împreună cu toate clasele descendente (direct sau indirect) formează o ierarhie de clase. poate fi superclasă pentru o altă clasă derivată.diferenţele dintre operarea la nivel abstract (cu DTA) şi apelul metodei ce realizează această operaţie la nivel de implementare obiectuală. În C#. Clasa care moşteneşte se numeşte subclasă. O subclasă. modificatori ce obligă la şi respectiv se opun procesului de derivare. Moştenire Definiţie: Pentru tipurile de date obiectuale class este posibilă o operaţie de extindere sau specializare a comportamentului unei clase existente prin definirea unei clase noi ce moşteneşte datele şi metodele clasei de bază. Deşi ajută la sporirea expresivităţii codului.   I.cantitate) cu primul parametru întreg şi celalalt real comanda_online(cod_prod.

să aibă comportamente diferite. referirea la metoda muta pare nedefinită. se manifestă în lucrul cu obiecte din clase aparţinând unei ierarhii de clase. în momentul apelului. Acest lucru este posibil doar în cazul limbajelor ce permit „legarea întârziată”. în C# 80 . a clasei proxime căreia îi aparţine obiectul T şi apelarea metodei corespunzătore (mutare de pion sau tură sau altă piesă). Polimorfism. pentru un obiect T. pozitie_finala). Metode virtuale Definiţie: Folosind o extensie a sensului etimologic. Comportamentul polimorfic este un element de flexibilitate care permite stabilirea contextuală. adresa la care se face un apel al unui subprogram se stabileşte la compilare. unde. Polimorfismul obiectual. atunci subclasele TURN şi PION trebuie să aibă metoda muta definită în mod diferit (pentru a implementa maniera specifică a pionului de a captura o piesă „en passant”. Exemplul 59: Dacă este definită clasa numită PIESA (de şah).Definiţie: O metodă abstractă este o metodă pentru care nu este definită o implementare. Pentru a permite acest mecanism. se obţin membri diferiţi având însă acelaşi nume. într-o altă concepţie. Totuşi mecanismele POO permit stabilirea. Atunci. în funcţie de contextul în care apare apelul. în cazul unei referiri obiectuale. se pune problema stabilirii datei sau metodei referite. Astfel. La limbajele cu legare întârziată.5. un obiect polimorfic este cel capabil să ia diferite forme. această adresă se stabileşte doar in momentul rulării. cu metoda nestatică muta (pozitie_initiala. aceasta urmând a fi realizată în clasele derivate din clasa curentă care trebuie să fie şi ea abstractă (virtuală pură. metoda muta poate fi implementată la nivelul clasei PIESA şi redefinită la nivelul subclasei PION. putându-se calcula distinct. în mod dinamic. se declară ca metode virtuale (cu modificatorul virtual).3. să se afle în diferite stări. La limbajele cu „legare timpurie”. a membrului referit. conform terminologiei din C++). I. aparţinând claselor derivate din PIESA. prin redefinirea unor date sau metode. În mod curent. pentru a particulariza acest tip de deplasare care capturează piesa peste care trece pionul în diagonală). metodele care necesită o decizie contextuală (în momentul apelului). care trebuie să fie abstract. Definiţie: O metodă sigilată este o metodă care nu mai poate fi redefinită în clasele derivate din clasa curentă. sau.

entităţilor din domeniul problemei se definesc prin clase.4. asociate noţiunii de clasă. de obicei. I. Polimorfismul . va fi invocată metoda din clasa de bază. indiferent de clasa căreia îi aparţine obiectul. îi corespunde un specificator override al funcţiei din clasa derivată ce redefineşte funcţia din clasa de bază. astfel încât programele realizate prin tehnica POO sunt mai uşor de înţeles. 4. Definirea nivelului de acces la datele unui obiect 3. Aceasta este adevărată mai ales în cazul proiectelor software complexe şi de dimensiuni mari. Obiectele POO sunt. clasă ce nu se instanţiază.6. Rezultatul este un model. Structura unei aplicaţii orientată pe obiecte în C# Limbajul C# permite utilizarea programării orientate pe obiecte respectând toate principiile enunţate anterior. 2.posibilitatea mai multor obiecte dintr-o ierarhie de clase de a utiliza denumiri de metode cu acelaşi nume dar. reprezentări ale obiectelor din viaţa reală (domeniul problemei). Gruparea comportamentelor şi caracteristicilor într-un tip abstract de date b.modificatorului virtual al funcţiei din clasa de bază. încapsularea – numită şi ascunderea de informaţii. Principiile POO sunt: 1. moştenirea – organizează şi facilitează polimorfismul şi încapsularea permiţând definirea si crearea unor clase specializate plecând de la clase (generale) care sunt deja definite acestea pot împărtăşi (şi extinde) comportamentul lor fără a fi nevoie de redefinirea aceluiaşi comportament. Toate componentele limbajului sunt într-un fel sau altul. în loc de simple liste de instrucţiuni sau de apeluri de proceduri. de depanat şi de extins decât programele procedurale. O metodă ne-virtuală nu este polimorfică şi. 81 . este caracterizată prin 2 aspecte: a. Principiile programării orientate pe obiecte Ideea POO este de a crea programele ca o colecţie de obiecte. Programul însuşi este o clasă având metoda statică Main() ca punct de intrare. cu un comportament diferit.3. I. abstractizarea . unităţi individuale de cod care interacţionează unele cu altele. În urma abstractizării.principiu care permite identificarea caracteristicilor şi comportamentului obiectelor ce ţin nemijlocit de domeniul problemei.

2.    pot exista mai mulţi constructori care se pot diferenţia prin lista lor de parametri constructorii nu pot fi moşteniţi dacă o clasă nu are definit niciun constructor. I. Tot din ierarhia de clase oferită de limbaj se obţin şi tipuri speciale cum ar fi: interfeţe. class – cuvânt rezervat pentru noţiunea de clasă Copil – numele clasei { } – corpul clasei Dacă considerăm clasa Copil ca şi clasă de bază.4. fără a intra în detalii o aplicaţie POO simplă în C#. Clasă de bază şi clase derivate Să definim o clasă numită Copil: public class Copil { } unde: public – sunt modificatori de acces.4. echivalentul claselor template din C++.1. se va asigna automat constructorul fără parametri al clasei de bază (clasa object. delegări şi atribute. în cazul constructorilor cu modificatorul static). putem deriva două clase Fetiţa şi Băiat Copil Fetita Baiat public class Fetita: Copil { } public sealed class Baiat: Copil { } unde: modificatorul sealed a fost folosit pentru a desemna faptul că nu se mai pot ob ine clase derivate din clasa Baiat I.0 a limbajului i s-a adăugat un nou tip: clasele generice. int sau bool sunt clase sigilate derivate din clasa ValueType din spaţiul System. Constructori Înainte de a continua amintim câteva noţiuni legate de constructorii unei clase: Constructorul este o funcţie care face parte din corpul unei clase.Chiar şi tipurile predefinite byte. Corpul constructorului este format din instrucţiuni care se execută la crearea unui nou obiect al clasei respective (sau la crearea clasei. dacă nu este precizată clasa de bază) 82 . În cele ce urmează vom analiza. Începând cu versiunea 2.

Exemplul 60: public class Copil { protected string nume. Reluăm exemplu de mai sus în care vom prezenta un constructor fără parametri şi constructorul implicit din clasa derivată. } } class Fetita: Copil { } . Supraîncărcarea constructorilor şi definirea constructorilor în clasele derivate Reluăm exemplul anterior şi îl dezvoltăm: 83 . Fetita f = new Fetita ( ). Vom adăuga un constructor fără parametri..4.3.ReadLine( ). dacă sunt definiţi mai mulţi) precedat de operatorul new.. public Copil ( ) { nume = Console.Instanţierea presupune declararea unei variabile de tipul clasei respective şi iniţializarea acesteia prin apelul constructorului clasei (unul dintre ei. La iniţializarea obiectului se va citi de la tastatură un şir de caractere care va reprezenta numele copilului. //data accesibila numai in interiorul //clasei si a claselor derivate //constructorul fara parametrii ai clasei I. Copil c = new Copil ( ).

Fetita f2 = new Fetita ("Maria"). Exemplul 61: 84 . Exemplificarea o vom face tot pe exemplul anterior.public class Copil { protected string nume. destructorul nu este apelat în mod explicit.ReadLine( ). Destructorii nu pot fi moşteniţi. Copil c1 = new Copil ( ).. Destructor Corpul destructorului este format din instrucţiuni care se execută la distrugerea unui obiect al clasei respective.5.4.. //constructorul //din clasa de baza } } . } class Fetita: Copil { public Fetita (string s): base(s) //base semnifica faptul ca { //se face apel la nume = "Fetita "+ nume.} public Copil (string s) //constructor cu parametru {nume = s.4. //numele copilului se citeste de la //tastatura Copil c2 = new Copil ("Gigel"). Metode Din corpul unei clase pot face parte şi alte funcţii: metodele. //numele lui c2 va fi Gigel Fetita f1 = new Fetita ( ). deoarece procesul de distrugere a unui obiect este invocat şi gestionat automat de Garbage Collector I. În mod normal.4. //data accesibila numai in interiorul //clasei si a claselor derivate public Copil ( ) //constructorul fara parametrii ai clasei {nume = Console.} I. Pentru orice clasă poate fi definit un singur constructor.

.adaug_copil(c).adaug_copil(c). } public static void afisare() //metodă { Console. //referinţa noului obiect se memorează în tabloul static copii //(caracteristic clasei) şi se incrementează data statică nr_copii Baiat c = new Baiat().. Copil. //data accesibila numai in interiorul //clasei si a claselor derivate public const int nr_max = 10. i++) Console.WriteLine("Sunt {0} copii:".public class Copil { protected string nume. Copil. } public Copil() //constructorul fara parametrii ai clasei { nume = Console. if (nr_copii == nr_max) throw new Exception("Prea multi copii").nume). {1}".afisare(). } } class Fetita : Copil { public Fetita(string s) : base(s) { nume = "Fetita " + nume. } public Copil(string s) { nume = s. //camp de tip //tablou (variabila) public static void adaug_copil(Copil c) //metodă { copii[nr_copii++] = c. i + 1. Definirea datelor şi metodelor nestatice corespunzătoare clasei Copil şi claselor derivate Exemplul 62: 85 . for (int i = 0.ReadLine().WriteLine("Nr. i < nr_copii. //camp simplu (variabila) static Copil[] copii = new Copil[nr_max]. //din clasa de baza } } //constructor cu parametru //base semnifica faptul ca //se face apel la //constructorul Fetita c = new Fetita(). nr_copii). Copil.adaug_copil(c). //se afişează o listă cu numele celor 3 copii .{0}. copii[i]. //constanta public static int nr_copii = 0. Copil. Copil c = new Copil().

metoda set este asimilabilă cu o metodă care un parametru de tip valoare (de intrare) şi care 86 . I.6. Metodele de acces sunt două: set şi get. b. poate să apară una singură dintre cele două metode de acces sau amândouă.nume). definind instrumente de acces la acestea: pentru a obţine valoarea câmpului respectiv (get) sau de a memora o anumită valoare în câmpul respectiv (set).jucaria). //polimorfism Fetita f = new Fetita( ).". this.se_joaca("calculatorul"). } .se_joaca("pisica")..WriteLine("{0} chinuie pisica.". } public void se_joaca(string jucaria) //supradefinirea metodei { //se_joaca Console.". Proprietăţi Proprietăţile sunt asemănătoare cu metodele în ceea ce priveşte modificatorii şi numele metodelor. f.public class Copil { protected string nume. b. public virtual void se_joaca( ) //virtual – functia se poate { //suprascrie la derivare Console. în orice ordine. Dacă metoda de acces get este perfect asimilabilă cu o metodă ce returnează o valoare (valoarea datei pe care vrem s-o obţinem sau valoarea ei modificată conform unei prelucrări suplimentare specifice problemei în cauză). } class Fetita: Copil { public override void se_joaca( ) //redefinire { Console.this. f.se_joaca( ).. } } . Dacă proprietatea nu este abstractă sau externă. Baiat b = new Baiat ( ). this.. Este o manieră de lucru recomandabilă aceea de a proteja datele membru (câmpuri) ale clasei.WriteLine("{0} se joaca.4.. .nume.WriteLine("{0} se joaca cu {1}..nume)..se_joaca( ).

În proiectarea unei aplicaţii POO parcurgem următoarele etape: 1.ReadLine( ). } set { nume = value. Exemplul 63: public class Copil {.WriteLine("{0} leagana papusa. este de ştiut că el este implicit identificat prin cuvântul value. Definirea în clasa Copil a proprietăţii Nume.Nume). acestea vor realiza prelucrările care definesc comportarea sistemului. prin evidenţierea verbelor şi adjectivelor care caracterizează subiectul respectiv 3. } } public Copil() //metoda set { Nume = Console. identificarea relaţiilor dintre entităţi 4.IsUpper(nume[0])) return nume.4. corespunzătoare câmpului protejat ce reţine. identificarea entităţilor.ToUpper(). string nume. prin evidenţierea substantivelor din enunţul problemei 2. else return nume. Se va observă că proprietatea este moştenită şi de clasele derivate Fetiţa şi Băiat. se face o atribuire de felul câmp=value.atribuie (sau nu. numele copilului respectiv. sub forma unui şir de caractere. Obiectele sunt responsabile pentru modificarea datelor proprii. pentru fiecare obiect se identifică datele şi operaţiile. Dacă se supune unor condiţii specifice problemei.this. Concluzie Scrierea unui program orientat obiect implică determinarea obiectelor necesare. } } class Fetita:Copil { public override void se_joaca() //metoda get { Console. pornind de la aceste entităţi 87 .7..".. adică a obiectelor care apar în domeniul aplicaţiei. Cum parametrul corespunzător valorii transmise nu apare în structura sintactică a metodei. } } I. crearea unei ierarhii de clase. // este implicit protected public string Nume //proprietatea Nume { get { if(char. în funcţie de context) valoarea respectivă câmpului.

Clase şi obiecte I. doar una dintre aceste clase conţine un punct de intrare . Sintaxa: [atribut][modificatorAcces] class [identificator][:clasaBaza] { corpul_clasei } unde: atribut – este opţional. testarea şi punerea la punct. Clase Clasele reprezintă tipuri referinţă definite de utilizator. Acces permis doar pentru clase interioare folosit pentru clase interioare semnificând accesul în clasa care-l conţine sau în tipurile derivate din clasa care-l conţine permis claselor interioare. clasa este vizibilă peste tot acces permis doar în clasa sau spaţiul de nume care o cuprinde acces în clasa curentă sau în cele derivate modificator implicit.5.1. iar în cazul în care lipseşte se consideră public modificatorAcces public internal protected private protected internal new sealed abstract Explicaţii acces nelimitat. grupate în spaţii de nume namespaces. O aplicaţie C# este formată din una sau mai multe clase. Se foloseşte pentru clase interioare sau spaţii de nume identificator .5.entry point. şi anume metoda Main. reprezentând informaţii declarative cu privire la entitatea definită modificatorAcces . neputând fi instanţiată.este numele clasei 88 . implementarea claselor şi a sistemului 6. Clasa cu acest modificator ascunde un membru cu acelaşi nume care este moştenit clasa nu poate fi moştenită clasa nu poate fi decât clasă de bază.este opţional. În mod obligatoriu.5. I.

namespace AplicatiiClase { public class IncludeClase { public class Clasa1 { } abstract class Clasa2 { } protected class Clasa3 { } internal class Clasa4 { } private class Clasa5 { } class Clasa6 { } } class Program { static void Main(string[] args) { IncludeClase.Clasa1 a. using System. din care derivă clasa actuală.Clasa4 d. //Eroare.Clasa6 f. //Eroare. IncludeClase.NET) 89 . Exemplul 64: Se consideră clasa IncludeClase care include şase clase având modificatori de acces diferiţi. using System. fiind numele clasei de bază.Clasa5 e. IncludeClase.este opţional. //Eroare. //Clasa3 este inaccesibila IncludeClase.Text. //Eroare. //Clasa5 este inaccesibila IncludeClase. //Clasa2 este inaccesibila IncludeClase. //Clasa6 este inaccesibila } } } Corpul clasei .clasaBaza .Clasa3 c.Collections.Generic.Clasa2 b.este alcătuit din:   date funcţii Atât datele cât şi funcţiile pot avea ca modificatori de acces: modificatorAcces public internal Explicaţii Membrul este accesibil de oriunde Membrul este accesibil doar în assembly-ul curent (bloc funcţional al unei aplicaţii . Se pune problema „vizibilităţii” lor din exterior using System.

descriu valori fixe. byte. putând fi valori calculate sau dependente de alte constante. double.reprezintă tipul datei obiectului pe care vrem să-l atribuim.1. Implicit este private. float. În mod obligatoriu valoarea unei astfel de constante trebuie să fie calculată în momentul compilării. int. Declararea datelor se face: [modificatorAcces] tipData nume. ulong. ushort.(1) Date Datele situate într-o clasă sunt desemnate sub numele de variabile sau atribute. char. enum.protected private protected internal Membrul este accesibil oricărui membru al clasei care-l conţine şi a claselor derivate Modificator implicit. Sintaxa este: [modificator] const tip identificator = expresieConstanta [modificator] const tip identificator = expresieConstanta unde tip poate fi: bool.5. string 90 . nume . Datele pot fi de orice tip.se referă la numele dat de utilizator obiectului respectiv. inclusiv alte clase. Accesibil permis doar pentru clasa care-l conţine Membrul este accesibil oricărui membru al clasei care-l conţine şi a claselor derivate. precum şi în assembly-ul curent I. long. uint. sbyte. unde: modificatorAcces . câmpuri. decimal. tipData . Datele pot fi:   constante. Valoarea unei constante se declară prin cuvântul const. short.este opţional. Constantele .

//implicit private static void Main(string[] args) { Camp obiect = new Camp(). obiect. Deoarece un astfel de câmp are o valoare specifică fiecărui obiect.Constanta mai poate avea ca modificator de acces: internal. fie printr-o calificare bazată pe numele clasei sau al unui obiect.reprezintă o dată variabilă a unei clase. new.2. private int id = 13. } Câmpul . } } Câmpuri de instanţă În cazul în care într-o declaraţie de câmp nu este inclus modificatorul static.a = 1. readonly. public. accesarea lui se va face folosind numele obiectului: obiect. 91 . static. protected internal. Opţional. se mai adaugă: new. private. Exemplul 65: class Constante { public const int MAX = 100. Un astfel de câmp se poate folosi fie prin specificarea numelui său. const string SALUT = "Buna ziua!". public const double MIN = MAX / 3. Sintaxa este: tip identificator [=valoare] Exemplul 66: class Camp { public int varsta. volatile. int a. protected string nume.a = 1. atunci respectivul câmp se va regăsi în orice obiect de tipul clasei curente care va fi instanţiat. câmpurile pot fi iniţializate cu valori compatibile. protected. În afară de modificatorii menţionaţi mai sus.

Câmpuri volatile Câmpurile volatile se declară cu ajutorul cuvântului volatile.} //camp readonly initializat } În momentul compilării valoarea câmpului readonly nu se presupune a fi cunoscută. ushort. Accesarea unui astfel de câmp din exteriorul clasei se poate face doar prin intermediul numelui de clasă: Exemplul 67: class Camp { public static int a = 13. sbyte. public class Camp(string b) //constructor {this.a++. Atribuirea se face doar la declararea sa. float. } } Câmpuri readonly Pentru a declara un câmp readonly se va folosi cuvântul readonly în declaraţia sa. câmpul respectiv va aparţine clasei. care poate fi ataşat doar următoarelor tipuri:  byte. static void Main(string[] args) { Camp. char.Un câmp special este this care reprezintă o referinţă la obiectul curent Câmpuri statice Dacă într-o declaraţie de câmp apare specificatorul static. //camp readonly initializat public readonly string b. sau prin intermediul unui constructor: Exemplul 68: class Camp { public readonly string a = “Exemplu”. int. uint. short.b = b. bool 92 .

  un tip enumerare care are tipul: byte. short.(2) Funcţii Funcţiile pot fi:        Constructori Destructori Metode Proprietăţi Evenimente Indexatori Operatori I.5. uint un tip referinţă Iniţializarea câmpurilor Valorile implicite pe care le iau câmpurile la declararea lor sunt: tip numeric bool char enum referinţă valoare 0 false \0 0 null I. int.1.5. Constructorii au acelaşi nume cu al clasei.1. ushort.(3) Constructori Definiţie: Constructorii sunt funcţii care folosesc la iniţializarea unei instanţe a clasei. sbyte. Constructorul poate avea un modificator de acces şi nu returnează nimic. Sintaxa este: modificatorAcces numeConstructor([parametri])[:initializator] [{ corp_constructor }] 93 .

Dacă nu se precizează niciun iniţializator. public Elev() //constructor { nume = "". } } Apelul unui constructor se face automat la instanţierea clasei prin operatorul new. } public Elev(string Nume) //constructor { nume = Nume. Exemplul 70: class Elev { public string nume. } Exemplul 69: Constructor cu doi parametri 94 . Iniţializatorul poate lua două forme: base([parametri]) sau this([parametri]).unde: initializator – permite invocarea unui constructor anume. Exemplul 71: class Exemplu_71 { Elev elev = new Elev(). diferenţiaţi după numărul şi tipul de parametri. înainte de executarea instrucţiunilor care formează corpul constructorului curent. C# va crea unul implicit având corpul vid. Exemplul 69: class Elev { public Elev() { } } //constructor O clasă poate conţine mai mulţi constructori. implicit se va asocia base( ). În cazul în care nu definim nici un constructor.

1. namespace Complex { class Complex { private int re. } public void Afis() { Console.5. fiind precedat de caracterul „~”.Afis(). Într-o clasă există un singur destructor. //constructor cu doi parametri public Complex(int i. 2).(4) Destructori Destructorul clasei implementează acţiunile necesare distrugerii unei instanţe a clasei. int j) { re = i. } } class Program { static void Main(string[] args) { Complex c = new Complex(1.WriteLine(re + "+" + im + "i"). Console. im = j. } } } Observaţie: Constructorii nu pot fi moşteniţi.ReadLine(). Destructorul nu poate fi moştenit. I. Destructorul este apelat automat. Numele destructorului coincide cu numele clasei. private int im. Destructorul nu are parametri şi nici modificator de acces.using System. c. Exemplul 73: 95 .

5.using System. tipul este void. using System. Valoarea returnată de către o metodă nu poate să fie luată în considerare în cazul supradefinirii.WriteLine("Apel destructor"). namespace Mesaj { class Program { static void Main(string[] args) { Mesaj a = new Mesaj(). Sintaxa este: modificatorAcces tipReturnat numeMetoda([parametri]) [{ corp_Metoda }] unde: modificatorAcces . } ~Mesaj() { Console. Metoda poate admite parametri şi returna valori. adică se pot defini mai multe metode.Generic. În cazul în care lipseşte se consideră implicit 96 . Metodele pot fi supradefinite (supraîncărcate).ReadLine(). } class Mesaj { public Mesaj() { Console. Console. Metode Metoda este un membru al unei clase care implementează o acţiune. dar să difere prin numărul şi tipul de parametri. } } } } I. using System.Text. care să poarte acelaşi nume.3. În cazul în care metoda nu returnează nimic.) sau de tip obiect (class).2.este opţional. bool etc.1.Collections.WriteLine("Apel constructor"). Tipul returnat de către o metodă poate fi unul predefinit (int.

precum şi new. corpul metodei se poate reduce la un semn . virtual. tipReturnat – poate fi un tip definit sau void. declararea unui parametru având sintaxa: [atribut][modificator] tip nume Modificatorul unui parametru poate fi ref (parametru de intrare şi ieşire) sau out (parametru care este numai de ieşire).[nume_metoda] pentru metodele nestatice pentru metodele statice 97 . override. numărul şi tipul parametrilor. abstract. numele este de forma: [numeInterfata]. Un parametru formal special este parametrul tablou cu sintaxa: [atribut] params tip [ ] nume Pentru metodele abstracte şi externe. Semnătura fiecărei metode este formată din numele metodei. numele parametrilor formali şi nici specificatorii ref şi out. sealed.private. în cazul în care defineşte în mod explicit un membru al unei interfeţe. Parametrii care nu au niciun modificator sunt parametri de intrare. Din semnătură (amprentă) nu fac parte tipul returnat. modificatorii acesteia. orice parametru trebuie să aibă acelaşi modificator ca la definire Invocarea unei metode se realizează prin: [nume_obiect].poate fi un simplu identificator sau. numeMetoda . static. modificatorAcces poate fi orice modificatorAcces amintit. La apelul metodei.[nume_metoda] [nume_clasă]. Numele metodei trebuie să difere de numele oricărui alt membru care nu este metodă.[numeMetoda] parametri .lista de parametri formali este o succesiune de declarări despărţite prin virgule. extern.

Cum parametrul 98 . definind instrumente de acces la acestea: pentru a obţine valoarea câmpului respectiv (get) sau de a memora o anumită valoare în câmpul respectiv (set). precum şi new. metoda set este asimilabilă cu o metodă care un parametru de tip valoare (de intrare) şi care atribuie (sau nu. override.I. Accesorul get corespunde unei metode fără parametri. Proprietăţi Proprietatea este un membru al clasei care ne permite să accedem sau să modificăm caracteristicile unui obiect sau al clasei. Dacă proprietatea nu este abstractă sau externă. virtual. poate să apară una singură dintre cele două metode de acces sau amândouă.1. Sintaxa este: [atribut]modificatorAcces tipReturnat numeProprietate { get { } set { } } unde: modificatorAcces . de tipul proprietăţii şi tip de retur void. în funcţie de context) valoarea respectivă câmpului. Accesorul set corespunde unei metode cu un singur parametru. sealed. extern.poate fi orice tip valid în C#. Dacă metoda de acces get este perfect asimilabilă cu o metodă ce returnează o valoare (valoarea datei pe care vrem s-o obţinem sau valoarea ei modificată conform unei prelucrări suplimentare specifice problemei în cauză).4.poate fi orice modificatorAcces amintit.5. static. Este o manieră de lucru recomandabilă aceea de a proteja datele membru (câmpuri) ale clasei. care returnează o valoare de tipul proprietăţii. în orice ordine. tipReturnat . abstract. el specificând tipul folosit de accesorii get (tipul valorii returnate) şi set (tipul valorii atribuite).2.

Collections. este de ştiut că el este implicit identificat prin cuvântul value.P. // linia urmatoare apeleaza accesorul //'get' din proprietatea P Console.ReadLine(). Console.corespunzător valorii transmise nu apare în structura sintactică a metodei. x = value. return x. } } } class Program { public static void Main(string[] args) { ClasaMea obiect = new ClasaMea(). using System.Text.WriteLine("get"). } } } 99 .WriteLine("set"). using System. namespace GetSet { class ClasaMea { private int x. public int P { get { Console. Exemplul 74: using System.P = 10.WriteLine(xVal). } set { Console. int xVal = obiect. //linia urmatoare apeleaza accesorul //'set' din proprietatea P si ii //paseaza 10 lui ‘value’ obiect.Generic.

Clasa furnizoare a unui eveniment publică (pune la dispoziţia altor clase) acest lucru printr-o declarare event care asociază evenimentului un delegat.1. Sintaxa: [atribut][modificatorAcces]even tipDelegat nume unde: modificatorAcces . adică o referinţă către o funcţie necunoscută căreia i se precizează doar antetul. derivat din clasa sigilată Delegate din spaţiul System.(5) Evenimente şi delegări Evenimentele sunt membri ai unei clase ce permit clasei sau obiectelor clasei să facă notificări.este la fel ca în cazul metodelor tipDelegat – este un tip de date. adică să anunţe celelalte obiecte asupra unor schimbări petrecute la nivelul stării lor. Este modul prin care se realizează comunicarea între obiecte.5. Definirea unui tipDelegat se realizează astfel: [atribut][modificatorAcces] delegate tipRezultat nume[listaParametri]) Un delegat se poate defini şi în afara clasei generatoare de evenimente şi poate servi şi altor scopuri în afara tratării evenimentelor 100 . Tehnica prin care clasele implementează metode (handler-e) ce răspund la evenimente generate de alte clase poartă numele de tratare a evenimentelor.I. funcţia urmând a fi implementată la nivelul claselor interesate de evenimentul respectiv.

else return false. } while (Console.KeyChar != '\x001B'). v[i + 1])) return false.1.Generic.scrie(). object t2).Next(0. i++) v[i] = rand. public int[] v = new int[nmax]. object t2) { if ((int)t1 >= (int)t2) return true.WriteLine("Monoton descrescator"). if (x. x. metodă ce verifică dacă vectorul este o succesiune crescătoare sau descrescătoare. using System.aranj(f1)) Console.Text. } public void scrie() { for (int i = 0.Exemplul 75: dorim să definim o metodă asociată unui vector de numere întregi. for (int i = 0. 5).aranj(f2)) Console. namespace Delegari { public delegate bool pereche_ok(object t1.Linq. if (x. } } class Program { public static bool f1(object t1. object t2) { if ((int)t1 <= (int)t2) return true. v[i]). using System. using System. Console. } public bool aranj(pereche_ok ok)//ok e o delegare către o //funcţie necunoscută { for (int i = 0.ReadKey(true). public Vector() { Random rand = new Random().Collections. ". return true. else return false. i < nmax.Write("{0}. O implementare „generică” se poate realiza folosind delegări: using System.WriteLine(). //Escape } } } 101 . } public static bool f2(object t1. i++) if (!ok(v[i]. do { x = new Vector(). i++) Console. i < nmax .WriteLine("Monoton crescator"). } static void Main(string[] args) { Vector x. i < nmax. public class Vector { public const int nmax = 4.

extern.1. Cumulând mai multe astfel de referinţe. În clasa Vector. va implementa o metodă M ce realizează animaţia şi va adăuga pe M (prin intermediul unui delegat) la x. I. la interschimbarea valorilor a două componente se invocă delegatul E. private. public.(6) Indexatori Sunt cazuri în care are sens să tratăm o clasă ca un array. Se defineşte un tip delegat TD (să zicem) cu nişte parametri de interes(de exemplu indicii componentelor interschimbate) şi un eveniment care are ca asociat un delegat E (de tip TD). virtual. x.E+=new [tip_delegat](M). abstract. Sintaxa: [atribut][modificatorIndexator] declaratorDeIndexator { declaratiiDeAccesor } unde: modificatorIndexator – poate fi new. protected. descriem pe scurt un exemplu teoretic de declarare şi tratare a unui eveniment. internal. 102 . în metoda sort. override. În clasa Vector se consideră că interschimbarea valorilor a două componente ale unui vector e un eveniment de interes pentru alte obiecte sau clase ale aplicaţiei. Orice obiect x din clasa Vector are un membru E (iniţial null).Revenind la evenimente. Invocarea lui E realizează de fapt activarea tuturor metodelor adăugate la E. O clasă C interesată să fie înştiinţată când se face vreo interschimbare într-un vector pentru a genera o animaţie (de exemplu).E ajunge un fel de listă de metode (handlere). Cei care au studiat C++ vor observa că este o generalizare a supraîncărcării operatorului [ ] din respectivul limbaj. sealed.5.

trebuie să conţină accesorul get sau accesorul set. Pe când o proprietate poate fi declarată statică. declaratiiDeAccesor – asemănătoare cu cele de la proprietăţi. acest lucru este interzis în cazul indexatorilor. Când folosim un indexator. pe când un vector trebuie să aibă indicii de tip întreg indexatorii pot fi supradefiniţi. parametru care nu trebuie să fie de tipul ref sau out.declaratorDeIndexator – are forma: tipReturnat this [listaParametrilorFormali] unde: listaParametrilorFormali – trebuie să conţină cel puţin un parametru. sintaxa este asemănătoare cu cea de la vectori. Observaţie: Indexatorii şi proprietăţile sunt asemănătoare în ceea ce priveşte utilizarea accesorilor get şi set. la fel ca metodele. pe când vectorii da Exemplul 76: 103 . Un indexator poate fi privit ca o proprietate cu mai multe valori. pe când vectorii nu indexatorii nu pot fi folosiţi ca parametrii ref sau out. Totuşi există deosebiri:    indexatorii pot folosi indici nenumerici.

using System.Linq. } set { data[index] = value.".using System.1.ReadLine(). v[0]. v[1].(7) Operatori Definiţie: operatorul este un membru care defineşte semnificaţia unei expresii operator care poate fi aplicată unei instanţe a unei clase. using System. Sintaxa: [atribut] modificatorOperator declaratieDeOprator corpOperator Observaţia 1: Operatorii trebuiesc declaraţi publici sau statici. 104 . operatorul corespunde supraîncărcării din respectivul limbaj. namespace Exemplul_76 { class ClasaMea { private string[] data = new string[6].Text. v[1] = "cu". Console. Console. v[2]). v[0] = "Exemplu".WriteLine("{0} {1} {2}. public string this[int index] { get { return data[index].Generic. Nu se admit parametri de tip ref sau out.Collections. } } } I. using System. Observaţia 2: Parametrii operatorilor trebuie să fie de tip valoare. Pentru cei care cunosc C++. } } } class Rezultat { public static void Main() { ClasaMea v = new ClasaMea().5. v[2] = "indexatori".

Operatorii true şi false trebuie să fie ambii definiţi pentru a prevenii o eroare de compilare. y = j. } public static Complex operator -(Complex c) { Complex temp = new Complex(). temp. Se pot declara operatori: unari. binari şi de conversie. temp.Generic. } public void Afis() { Console. acelaşi modificator. Un operator ++ sau –. Exemplul 77: using using using using System. System. namespace Exemplul_77 { class Complex { private int x. System. de mai multe ori.! ˜ ++ – true false.Text.trebuie să returneze un rezultat de tip T şi preia un singur parametru de tip T 3. Reguli pentru supraîncărcarea operatorilor unari: Fie T clasa care conţine definiţia operatorului 1.y = -c.! ˜ poate returna orice tip şi preia un singur parametru de tip T 2. System.x.Observaţia 3: În antetul unui operator nu poate apărea. return temp.WriteLine("{0} {1}i".x = -c. int j) { x = i. y).Collections. Operatori unari Supraîncărcarea operatorilor unari are următoarea sintaxă: tip operatorUnarSupraîncărcabil (tip identificator) corp Operatorii unari supraîncărcabili sunt: + . } } 105 . x.Linq.y. private int y. public Complex() { } public Complex(int i. Un operator unar true sau false returnează bool şi trebuie să preia un singur parametru de tip T. Un operator + .

ReadLine().Afis().Afis(). c2 = -c1. iar al doilea parametru de tip int 3.Afis(). Cel puţin unul din cei doi parametri trebuie să fie de tipul clasei în care respectivul operator a fost declarat 2. Un operator binar poate returna orice tip 4. Complex c2 = new Complex(). c1. Următorii operatori trebuie să se declare în pereche: a.* /  & | ^ << >> == != > < >= <= Reguli pentru supraîncărcarea operatorilor binari: 1. operatorii > şi < c. Operatorii de shift-are trebuie să aibă primul parametru de tipul clasei în care se declară. tip identificator) corp Operatorii binari supraîncărcabili sunt: + . } } } Operatori binari Supraîncărcarea operatorilor binari are următoarea sintaxă: tip operator operatorBinarSupraîncărcabil (tip identificator. operatorii == şi != b. Console. operatorii >= şi <= Exemplul 78: 106 .class Program { public static void Main() { Complex c1 = new Complex(10. c2. c2. 13).

return temp.Write("c2: "). Console.using using using using System.Collections. int j) { x = i. } public void Afis() { Console. temp.WriteLine("\nc3 = c1 + c2\n").Write("c3: ").Write("c1: "). Console. namespace ExempluOperatori { class Complex { private int x. c2. } } } public static Complex operator +(Complex c1. Console.Afis().y = c1.Afis().Generic. y).x + c2.x. } } class Program { static void Main(string[] args) { Complex c1 = new Complex(1. System. Complex c3 = new Complex().Afis(). Complex c2) { Complex temp = new Complex(). c1.y + c2. private int y.Text.Linq. y = j. System. temp. Console. System. x. 2). Console. c3. Complex c2 = new Complex(3. } Operatori de conversie 107 . c3 = c1 + c2.WriteLine("{0} {1}". public Complex() { } public Complex(int i. 4).y.ReadLine().x = c1.

public MyDigit() { } public MyDigit(int i) { x = i. System.Collections. System. putându-se pierde date Sintaxa: implicit operator tip(tip parametru) corp explicit operator tip(tip parametru) corp  Un operator de acest tip va face conversia de la tipul sursa (S) (tipul parametrului din antet) în tipul destinaţie (D) (tipul returnat). S şi D nu sunt baze una pentru cealaltă Exemplu 79: conversii dintr-un tip de bază într-o clasă şi un tip clasă într-un tip de bază folosind conversia operator: using using using using System. Operatorii de conversie pot fi:  impliciţi – se efectuează de la un tip ”mai mic” la un tip „mai mare” şi reuşesc întotdeauna. nepierzându-se date expliciţi – se efectuează prin intermediul expresiilor de conversie.Generic. } } 108 .Linq.x.Operatorul de conversie introduce o conversie definită de utilizator. S şi D au tipuri diferite 2.Text. namespace Exemplul_79 { class MyDigit { private int x. } public static explicit operator MyDigit(int val) { return new MyDigit(val). Această conversie nu va suprascrie conversiile predefinite. S sau D este clasa în care se face definirea 3. } public void ShowDigit() { Console. System. } public static implicit operator int(MyDigit md) { return md. O clasă poate să declare un operator de conversie de la un tip S la un tip D dacă: 1. S şi D nu sunt object sau tip interfaţă 4.WriteLine("{0}". x).

WriteLine(x). //Explicit md2. int x = md1.ReadLine().} class Program { public static void Main(string[] args) { MyDigit md1 = new MyDigit(10). Console. } } Exemplul 80: Conversia dintr-un tip clasă în altul folosind conversia operator: 109 . int y = 25. MyDigit md2 = (MyDigit)y. //Implicit Console.ShowDigit().

Collections.x * 20).ReadLine(). } public void Afis1() { Console. y = b.using using using using System. System. namespace OperatoriImplicitiExpliciti { class Clasa1 { public int x.Text. } public void Afis2() { Console. } public static explicit operator Clasa2(Clasa1 mc1) { Clasa2 mc2 = new Clasa2(mc1.Linq. Console. System. y. } } class Program { public static void Main(string[] args) { Clasa1 mc1 = new Clasa1(100).Generic.WriteLine(x). public Clasa1(int a) { x = a.Afis2().x * 10. mc1.WriteLine(x).Afis1(). return mc2. } } class Clasa2 { public float x.WriteLine(y). public Clasa2(float a. System. } } } 110 . float b) { x = a. mc1. mc2. Console. Clasa2 mc2 = (Clasa2)mc1.

StivaMea.Pop(). public class Stiva<TipElement> //clasa generica { private TipElement[] element.6. interfeţe. ceea ce permite construirea unui şablon. Clase şi funcţii generice Definiţie: genericele sunt şabloane (templates) sau modele care ajută la reutilizarea codului. structuri. care permit definirea tipului pe care stiva îl va avea.Push("a"). este prezenţa caracterelor < şi >. Ele permit definirea de funcţionalităţi şi metode care se adaptează la tipurile parametrilor pe care îi primesc. ca şi cum ar fi un parametru al clasei. Exemplul 81: Să considerăm clasa Stiva care permite stocarea de elemente. Ele descriu clase şi metode care pot lucra într-o manieră uniformă cu tipuri de valori diferite. Singura diferenţă faţă de declararea în mod obişnuit a unei clase. Exemplul 82: tipurile parametrizate pot fi aplicate claselor şi interfeţelor 111 . Această clasă are două metode Push() care permite introducerea de elemente şi Pop() care permite extragerea de elemente din stivă. delegaţi sau metode care sunt parametrizate printr-un tip pe care îl pot stoca sau manipula.I. La instanţierea clasei trebuie să declarăm tipul datelor utilizate. char x = StivaMea. public void Push(TipElement data) { // code corespunzator introducerii de elemente } public TipElement Pop() { // code corespunzator extragerii de elemente } } Stiva<char> StivaMea = new Stiva<char>(). Tipurile generice (parametrizate) permit construirea de clase.

System.Collections. public const int MAX_SIZE = 100. private int m_Index = 0. namespace Exemplul_84 { class Stiva { private object[] m_ItemsArray. } public Object Pop() { if (m_Index == 0) throw new InvalidOperationException("Nu putem extrage un element dintr-o stiva vida. using using using using System. Altul> { } class ClassInt1 : ClassGeneric1<int. System.interface IGeneric1<T> { } class ClassGeneric1<UnTip. int> { } class ClassInt2<T> : ClassGeneric1<int. System. public Stiva() { m_ItemsArray = new object[MAX_SIZE]."). vom considera că stiva nu poate conţine decât un anumit număr de elemente. return m_ItemsArray[--m_Index].Generic.Text.Linq. ceea ce ne va permite să utilizăm tablouri în C#. T> { } class ClassInt3<T. Pentru a simplifica problema. } } Exemplul 84: Dorim să implementăm o clasă Stiva care să permită adăugarea şi extragerea de elemente. U> { } Exemplul 83: tipurile parametrizate se pot aplica metodelor class clA { public void methode1<T>() { } public T[] methode2<T>() { return new T[10]. } 112 . U> : ClassGeneric1<int.

Acest lucru va duce la probleme de convertire care vor fi descoperite la execuţie Deoarece problema conversiei nu este detectată la compilare."). } } } Implementarea suferă de câteva probleme:   elementele clasei Stiva trebuie să fie convertite explicit atunci când se foloseşte clasa Stiva cu elemente element de tip valoare. alt cod pentru elemente de tip sir de caractere. 113 . va produce o excepţie la  execuţie. C# ne permite rezolvarea unor astfel de probleme introducând tipurile generice. Din acest motiv spunem: codul nu este type-safe. Concret putem implementa o listă de elemente de tip T. int numar = (int)stiva. m_ItemsArray[m_Index++] = item. lăsând libertatea utilizatorului să specifice tipul T la instanţierea clasei. } } class Program { static void Main(string[] args) { Stiva stiva = new Stiva().Push(1234). se realizează implicit o operaţie de boxing cu inserarea unui element şi o operaţie de tip unboxing cu recuperarea unui dorim să introducem în stivă elemente de tipuri diferite în aceea i instanţă a clasei Stiva. Acest lucru se va rezolva cu ajutorul tipurilor generice. stiva.public void Push(Object item) { if (m_Index == MAX_SIZE) throw new StackOverflowException("Nu se poate adauga un elemet: stiva este plina. Acest lucru duce la dublarea unor porţiuni din cod. Pentru a rezolva aceste neajunsuri s-ar putea implementa un cod pentru stive cu elemente de tip int.Pop().

").Linq.Exemplul 85: using using using using System.1. System. private int m_Index = 0. int numar = stiva. Prin utilizarea moştenirii se poate defini o clasă generală care defineşte trăsături comune la un ansamblu de obiecte. } } class Program { static void Main(string[] args) { Stiva<int> stiva = new Stiva<T>().7.Text. stiva. string sNumar = sstiva. public const int MAX_SIZE = 100.Push(1234). System.Pop().Collections. } public void Push(Object item) { if (m_Index == MAX_SIZE) throw new StackOverflowException("Nu se poate adauga un elemet: stiva este plina. System.7. } } } I. return m_ItemsArray[--m_Index]. } public T Pop() { if (m_Index == 0) throw new InvalidOperationException("Nu putem extrage un element dintr-o stiva vida. 114 .Push("4321"). namespace Exemplul_85 { class Stiva<T> { private T[] m_ItemsArray. Această clasă poate fi moştenită de către alte clase specifice. sstiva.Pop().Generic. m_ItemsArray[m_Index++] = item. Derivarea claselor (moştenire) Principiile moştenirii I. public Stiva() { m_ItemsArray = new T[MAX_SIZE]. fiecare dintre acestea adăugând elemente care-i sunt unice ei."). //nu mai este necesar cast Stiva<string> sstiva = new Stiva<string>().

fiind permisă doar derivarea publică În contextul mecanismelor de moştenire trebuie amintiţi modificatorii abstract şi sealed aplicaţi unei clase. în sensul că derivarea se admite doar dintr-o clasă de bază.  Pe baza a ceea ce am amintit. În acest fel se poate defini noţiunea de ierarhie de clase. modificatori ce obligă la şi respectiv se opun procesului de derivare. iar o clasă care o moşteneşte pe aceasta se numeşte clasă derivată. aceasta urmând a fi realizată în clasele derivate din clasa curentă. sau subclasă.O clasă care este moştenită se numeşte clasă de bază sau superclasă. o clasă abstractă trebuie obligatoriu derivată. admite doar moştenirea simplă. Clasa derivată moşteneşte toate elementele clasei de bază şi-şi adaugă altele proprii. Muzician clasa de bază (clasa generală) Violonist clasa derivată (clasa specializată) Exemplul 86: 115 . O metodă sigilată nu mai poate fi redefinită în clasele derivate din clasa curentă. Astfel. putem spune că o clasă derivată este o versiune specializată sau extinsă a clasei de bază. în timp ce o clasă sigilată (sealed) nu mai poate fi derivată (e un fel de terminal în ierarhia claselor). spre deosebire de C++.   Definirea unei clase derivate se face folosind sintaxa: class ClasaDerivata : ClasaDeBaza { … } O clasă derivată poate la rândul ei să fie clasă de bază pentru o altă clasă. Clasa derivată nu poate să şteargă nici un membru al clasei de bază. Limbajul C#. O metodă abstractă este o metodă pentru care nu este definită o implementare. deoarece direct din ea nu se pot obţine obiecte prin operaţia de instanţiere. sau clasă descendentă.

De exemplu.WriteLine("{0} canta".Text. Pentru aceasta se va folosi o expresie de tip base access.7.Generic. în aceasta.Collections. n. } } class Program { static void Main(string[] args) { Muzician m = new Muzician(). } } class Violonist : Muzician { public void CantaLaVioara(string nume) { Console.Canta("Andrei").WriteLine("{0} canta la vioara". Accesibilitatea membrilor moşteniţi Deseori. m. Violonist n = new Violonist(). o expresie de forma: base. namespace Exemplul_86 { class Muzician { public void Canta(string nume) { Console.Canta("Ilie"). dacă MembruB este un membru al clasei de bază. } } } I. using System. nume).CantaLaVioara("Andrei"). nume). n.using System. în procesul derivării. Console. pentru a-l folosi într-o clasa derivată vom folosi.MembruB 116 .ReadLine(). using System. avem nevoie de acces la membrii moşteniţi ai clasei de bază.2.

Console. namespace Exemplul_87 { class Program { class ClasaDeBaza { public string sir = "Sir din clasa de baza". } } } I.2.WriteLine("{0}". sir). cd. I.(1) Utilizarea cuvântului cheie protected Cuvântul cheie protected permite restrângerea accesului unui membru al clasei de bază doar la clasele sale derivate.ReadLine().3. public void afis() { Console. } } static void Main(string[] args) { ClasaDerivata cd = new ClasaDerivata().Text. using System.7.7.afis(). Membrii protejaţi moşteniţi devin în mod automat protejaţi.Exemplul 84: apelul din clasa derivată a unui membru al clasei de bază using System. base.Collections. Apelul constructorilor clasei de bază Exemplul 88: 117 . using System.Generic.WriteLine("{0}". Console.sir). } class ClasaDerivata : ClasaDeBaza { public string sir = "Sir din clasa derivata".

modificator de acces.class ClasaDeBaza { protected string var.7. Pentru declararea unei metode ca fiind virtuală se foloseşte cuvântul cheie virtual.7..3. Metode Prin mecanismul de moştenire avem posibilitatea reutilizării codului şi redefinirii (prin polimorfism) a metodelor. Aceste metode trebuie să aibă aceeaşi signatură (nume. I. Doar metodele virtuale ne statice şi/sau private pot fi redefinite într-o clasă derivată. Exemplul 89: 118 ..3. tip returnat şi parametri).(1) Virtual şi override O clasă declarată virtuală implică faptul că o metodă implementată în ea poate fi redefinită în clasele derivate. În clasele derivate se va folosi cuvântul cheie override pentru redefinirea metodei virtuale din clasa de bază. public ClasaDeBaza(string var) { this. } } //constructor clasa Derivata : ClasaDeBaza { public ClasaDeBaza(string var) : base(var) { .var = var. } } I.

3. proprietăţi.class ClasaDeBaza { public virtual void Metoda() { ..7. dacă vom considera arborele din figura următoare.. asemănătoare unei clase. } } I.(2) new Există cazuri în care în loc să redefinim o metodă avem nevoie să specificăm că metoda clasei derivate este o implementare nouă a respectivei metode.. Pentru aceasta vom folosi new cu semnificaţia că metoda are aceeaşi signatură cu a celei din clasa de bază.4. deoarece permit utilizarea polimorfismului într-un sens mai extins. iar derivarea claselor a fost concepută urmărind proprietăţile comune ale componentelor 119 .. } } class Derivata : ClasaDeBaza { public override void Metoda() { . în care AVERE este o clasă abstractă. care declară prin membrii săi (metode. Interfeţe Interfeţele sunt foarte importante în programarea orientată pe obiecte. dar dorim să mascăm definirea ei în clasa de bază.. evenimente şi indexatori) un „comportament” unitar aplicabil mai multor clase. comportament care nu se poate defini prin ierarhia de clase a aplicaţiei. Definiţie: O interfaţă este o componentă a aplicaţiei... } } class Derivata : ClasaDeBaza { public new void Metoda() { . Exemplul 90: class ClasaDeBaza { public virtual void Metoda() { . De exemplu.7. } } I..

Dacă în sens polimorfic spunem că Investiţie este şi de tip Bani şi de tip Avere. Acele clase care „aderă” la o interfaţă spunem că „implementează” interfaţa respectivă. De exemplu. putem determina venitul total: Exemplul 91: 120 . În exemplul nostru. iar moştenirea multiplă nu este admisă în C#. implementarea lor fiind furnizată de unele dintre clasele aplicaţiei. atunci o clasă VENIT nu este posibilă. deoarece ea ar moşteni de la toate clasele evidenţiate. AVERE Proprietate Imobiliara Teren Productiv Neproductiv Imobil De_folosinţă I_inchiriat Bani Bun Depunere B_inchiriat Mobilier Altul Investiţie Credit_primit Actiune Cotă Credit_acordat VENIT (din produse. atunci pentru o avere cu acţiuni la două firme. dacă presupunem că toate clasele subliniate implementează interfaţa VENIT. dar se admit derivări.unei averi. metodele respective. deoarece formula de calcul implementată acolo nu i se „potriveşte” şi ei. ci sunt pur şi simplu specificate. tot aşa putem spune că o clasă care implementează interfaţa VENIT şi clasele derivate din ea sunt şi de tip VENIT). un imobil închiriat şi o depunere la bancă. din dobânzi. inclusiv moşteniri multiple. dividende)  calc() Pentru metodele din cadrul unei interfeţe nu se dă nici o implementare. clasa Credit_acordat redefineşte metoda calc din clasa Investiţie. Toate clasele care moştenesc dintr-o clasă care implementează o interfaţă moştenesc. dar le pot şi redefini (de exemplu. Nu există instanţiere în cazul interfeţelor. fiecare dintre clasele care implementează interfaţa VENIT fiind obligată să furnizeze o implementare (după o formulă de calcul specifică) pentru metoda calc din interfaţă. se poate defini o interfaţă VENIT care să conţină antetul unei metode calc (să zicem) pentru calculul venitului obţinut. din chirii. Orice clasă care doreşte să adere la interfaţă trebuie să implementeze toate metodele din interfaţă. evident.

Excepţia se foloseşte pentru a semnala contextul în care apare acea situaţie deosebită Observaţie: Nu trebuie confundat termenul de excepţie cu cel de eroare sau „bug”..i<4. Actiune act2 = new Actiune(). venituri[1] = act2. Tratarea excepţiilor în C# Definiţie: O excepţie este un obiect care încapsulează informaţii despre o situaţie anormală. Pe lângă ierarhia de excepţii pe care limbajul C# o are inclusă. Venit[] venituri = new Venit()[4]. venituri[0] = act1. Exception SystemException OutOfMemoryException IOException NullReferenceException AplicationException Ierarhia excepţiilor 121 . Chiar dacă programatorul elimină toate bug-urile din programul său pot apărea erori pe care el nu le poate preveni:    încercare de deschidere a unui fişier inexistent împărţiri la zero etc. Depunere dep=new Depunere(). I_inchiriat casa = new I_inchiriat(). .8.calc(). În cazul în care o metodă întâlneşte o astfel de excepţie. venituri[3] = dep. programatorul îşi poate crea propriile sale tipuri excepţie. int t=0..Actiune act1 = new Actiune(). atunci respectiva excepţie va trebui „prinsă” în vederea tratării (rezolvării) ei. venituri[2] = casa. for(i=0. Excepţiile nu sunt concepute pentru prevenirea bug-urilor. În C# se pot arunca ca excepţii obiecte de tip System.Exception sau derivate ale lui.i++) t+=v[i]. I.

Exception) Explicaţii sunt constructori public virtual string HelpLink {get.} observăm că o excep ie poate conţine în interiorul să o instanţă a unei alte excepţii obţine sau setează o legătură către fişierul Help asociat excepţiei. Dintre acestea amintim: Excepţia ArrayTypeMismatchException DivideByZeroException IndexOutOfRangeException InvalidCastException OutOfMemoryException OverflowException StackOverflowException Explicaţii Incompatibilitate între tipul valorii memorate şi tipul tabloului Încercare de împărţire la zero Indexul tabloului depăşeşte marginile definite Operatorul cast incorect la execuţie Datorită memoriei insuficiente apelul lui new eşuează Depăşire aritmetică Depăşirea capacităţii (definite) stivei Observaţie: Este posibilă definirea de către programator a propriilor clase de excepţii. sau către o adresă Web returnează excepţia care este încorporată în excepţia curentă obţine un mesaj care descrie excepţia curentă obţine sau setează numele aplicaţiei sau al obiectului care a cauzat eroarea obţine o reprezentare de tip string a apelurilor de metode care au dus la apariţia excepţiei obţine metoda care a aruncat excepţia curentă C# defineşte câteva excepţii standard derivate din System. 122 .Dintre metodele şi proprietăţile clasei Exception amintim: Metodele şi proprietăţile clasei Exception public Exception( ) public Exception (string) public Exception (string. Acestea vor fi derivate din ApplicationException.} public virtual string StackTrace {get. Acestea sunt generate când se produc erori la execu ia programului.} public MethodBase TargetSite {get.Exception. set} public Exception InnerException {get. set.} public virtual string Message {get.} public virtual string Source {get.

ReadLine()). în program pot exista mai multe blocuri corespunzătoare catch.Parse(Console. Partea de program care poate genera excepţii o vom plasa într-un bloc try. Console. int j = int.Parse(Console. în funcţie de tipul său să poată trata respectiva eroare.Write("Introduceti un numar "). int i = int.Generic. namespace Exceptii1 { class Program { static void Main(string[] args) { try { Console. System.I. //Console.8. iar partea corespunzătoare tratării excepţiei. În cazul în care este găsit respectivul bloc catch programul continuă cu instrucţiunile din corpul catch. În cazul în care blocul try generează o excepţie. Aruncarea şi prinderea excepţiilor I. Având în vedere că într-un corp try pot să apară excepţii diferite.(1) Blocurile try şi catch POO oferă o soluţie pentru gestionarea erorilor: folosirea blocurilor try şi catch. execuţia programului este întreruptă. de cele care sunt susceptibile să conducă la erori. într-un bloc catch.Text.1.8.Linq. System. În cazul în care nu se găseşte nici un catch corespunzător. Runtime întrerupe execuţia şi caută un bloc catch apropiat care. System.1.Write("Introduceti inca un numar "). int x = i / j. programatorul va separa acele instrucţiuni care sunt sigure (adică nu pot fi generatoare de excepţii). În scrierea codului. Exemplul 91: using using using using System.WriteLine(e).ReadLine()). } //(1) //(2) 123 .Collections.WriteLine("Numarul nu este intreg"). } catch (OverflowException e) { Console.

8. Observaţie: Pentru a intercepta orice excepţii. unde: NumeExceptie trebuie să fie numele unei clase apropiate de excepţia avută în vedere excepţie – este un mesaj care apare în cazul în care apare excepţia. respectivele linii afişează informaţii despre excepţiile apărute. Prin aceasta se va crea o rutină care va intercepta şi trata toate excepţiile.WriteLine(e).(2) Instrucţiunea throw Programatorul poate să-şi compună modalităţi proprii de aruncare a erorilor folosind instrucţiunea throw: throw new NumeExceptie(exceptie). în urma execuţii programului. introduceţi date care să producă excepţia pe care blocul comentat ar trata-o şi veţi observa întreruperea.} } } /* catch (DivideByZeroException e) { //Console. iar aceasta nu este prinsă cu catch 124 . în cazul în care blocurile catch există. cu mesaj de eroare a rulării programului. //(3) Console.//(5) Să analizăm puţin programul de mai sus:  Dacă liniile (2) şi (3) nu sunt comentate. Încercaţi să comentaţi unul dintre blocurile catch. indiferent de tipul lor se va folosi catch fără   parametru.WriteLine("Programul ruleaza in continuare"). //(4) }*/ Console.WriteLine("Exceptia DivideByZero"). Linia (5) a fost pusă în program pentru a demonstra rularea fără probleme.1. I. Liniile (1) şi (4) au fost puse pentru a personaliza informaţiile referitoare la excepţiile apărute.

(5).Write("Introduceti o cifra ").ReadLine()). (7).WriteLine("Programul ruleaza in continuare").Parse(Console. (5). //(0) throw new ArgumentOutOfRangeException(exceptie). (6). programul se opreşte din execuţie. } } //(3) catch (ArgumentOutOfRangeException) //(4) { //(5) Console. (3). (6). //(6) } //(7) Console.WriteLine("Nu este cifra"). apare un mesaj de eroare privind faptul că se aşteaptă un bloc catch sau finally Dacă nici una dintre liniile programului nu este comentată. int i = int. } } } Să analizăm programul de mai sus:  Dacă comentăm liniile (1). (7) şi la rularea programului introducem un număr în loc de o cifră.Exemplul 92: class Program { static void Main(string[] args) { try //(1) { //(2) Console. la rulare. if (i < 0 || i > 9) { string exceptie = i + " nu este o cifra". iar ca mesaj apare utilizator în linia (0) irul definit de  Dacă vom comenta doar liniile aferente blocului catch (4). (4). chiar dacă introduce un număr în loc de o cifră vom obţine:  125 . (2).

O metodă ne-virtuală nu este polimorfică şi. care trebuie să fie abstract. respectivele instrucţiuni vor fi plasate într-un bloc finally. Pentru acest lucru. anumite instrucţiuni. prin redefinirea unor date sau metode.1. se declară ca metode virtuale (cu modificatorul virtual).I. va fi invocată metoda din clasa de bază. unde. Introducere În Capitolul 3 defineam noţiunea de polimorfism. Pentru a permite acest mecanism. se obţin membri diferiţi având însă acelaşi nume.(3) Blocul finally Limbajul C# permite ca la ieşirea dintr-un bloc try să fie executate obligatoriu. să aibă comportamente diferite. îi corespunde un specificator override al funcţiei din clasa derivată ce redefineşte funcţia din clasa de bază. folosind o extensie a sensului etimologic: un obiect polimorfic este cel capabil să ia diferite forme.1.8. se manifestă în lucrul cu obiecte din clase aparţinând unei ierarhii de clase. În mod curent. fie pentru a elibera resursele după părăsirea excepţiei. în C# modificatorului virtual al funcţiei din clasa de bază. să se afle în diferite stări. metodele care necesită o decizie contextuală (în momentul apelului). în cazul în care programatorul doreşte acest lucru.9.9. Polimorfism I. I. Polimorfismul obiectual. Blocul finally este util fie pentru a evita scrierea unor instrucţiuni de mai multe ori. indiferent de clasa căreia îi aparţine obiectul. 126 .

Pentru aceasta se va folosi un parametru de tip params.WriteLine("arg[{0}] = {1}".Generic. F(new int[] { 1. arg. } } } 127 . arg[i]). i. System. using using using using System. la apelul funcţiei. prin intermediul acelui singur parametru formal. } static void Main(string[] args) { F(). Prin această formă de polimorfism. Acest lucru va permite folosirea mai multor parametri actuali. System. 2.Collections.Limbajul C# admite trei tipuri de polimorfism:    polimorfism parametric polimorfism ad-hoc polimorfism de moştenire I. i < arg. i++) { Console.WriteLine("Apelul functiei F cu {0} parametri:". declarat folosind modificatorul params. } Console.WriteLine(""). for (int i = 0. namespace Exemplul_93 { class Program { static void F(params int[] arg) { Console. C.Text. o funcţie va prelucra orice număr de parametri.2. de tip vector. 3 }). 6).9.Length). Polimorfismul parametric Această formă de polimorfism este preluată de la limbajele neobiectuale: Pascal. F(4.Linq.Length. F(2). System. Exemplul 93: Să considerăm o funcţie F cu un parametru formal.

WriteLine("Functia F cu doi parametri: int si respectiv float\n"). Exemplul 94: using using using using System. namespace PolimorfismAdHoc { class Program { static void F() { Console. 3).9. Polimorfismul ad-hoc Acest tip de polimorfism se mai numeşte şi supraîncărcarea metodelor. se va apela o funcţie sau alta. Prin acest mecanism se pot defini în cadrul unei clase mai multe metode.3). System.WriteLine("Functia F cu doi parametri: int si respectiv int\n"). System. } static void F(int a. 6.Collections. în funcţie de parametri folosiţi la apel. int b) { Console. } static void Main(string[] args) { F(). toate având acelaşi nume.WriteLine("Functia F fara parametri\n").3.I. double b) { Console.Text. dar cu tipul şi numărul de parametri diferiţi. } } } 128 . F(2. La compilare. System.Generic. } static void F(int a.Linq. F(4.

Linq.Generic. Polimorfismul de moştenire În cazul acestui tip de moştenire vom discuta într-o ierarhie de clase.9. System. System. Baza obiect1 = obiect2. System.Afis().WriteLine("Apelul functiei Afis din clasa derivata\n").Text. } } class Derivata : Baza { public void Afis() { Console.WriteLine("Apelul functiei Afis din clasa de baza\n").Collections. } } class Program { static void Main(string[] args) { Derivata obiect2 = new Derivata(). obiect1.Afis().4. //(1) obiect2. În acest caz ne punem problema apelării metodelor. metode ce fac parte din clase diferite.I. //(2) } } } 129 . namespace Exemplul_95 { class Baza { public void Afis() { Console. Exemplul 95: using using using using System. având aceeaşi listă de parametri formali.

Baza obiect1 = obiect2. //(2) } } } 130 .WriteLine("Apelul functiei Afis din clasa de baza\n"). chiar dacă obiect1 a fost instanţiat pe baza unui obiect din clasa Derivata. obiect1. Deci linia (1) din program va duce la apelul lui Afis() din clasa Baza. //(1) obiect2. System. System. Modificatorii virtual şi override În cazul în care se doreşte ca apelul metodelor să se facă la rulare şi nu la compilare vom reconsidera exemplul anterior în care funcţia Afis( ) din clasa de bază o declarăm virtuală. } } class Derivata : Baza { public override void Afis() { Console.Afis().Linq.Collections.Text. System.Să discutăm despre prima linie afişată (cea de-a doua este evidentă). Apelul lui Afis() se rezolvă în momentul compilării pe baza tipului declarat al obiectelor. } } class Program { static void Main(string[] args) { Derivata obiect2 = new Derivata().WriteLine("Apelul functiei Afis din clasa derivata\n"). iar funcţia Afis( ) din clasa derivată o considerăm ca suprascriere a lui Afis( ) din clasa de bază: Exemplul 96: using using using using System. namespace Exemplul_96 { class Baza { public virtual void Afis() { Console.Generic.Afis().5. I.9.

System. Modificatorul new În cazul în care se doreşte ca o metodă dintr-o clasă derivată să aibă aceeaşi semnătură cu o metodă dintr-o clasă de bază. System.WriteLine("Apelul functiei Afis din clasa de baza\n").Collections. //(2) } } } 131 . obiect1. namespace PolimorfismDeMostenire { class Baza { public virtual void Afis() { Console.Linq.9. vom folosi modificatorul new. //(1) obiect2.Generic. Baza obiect1 = obiect2.I.Afis().6.WriteLine("Apelul functiei Afis din clasa derivata\n"). System. dar să nu fie considerată o suprascriere a ei.Afis(). } } class Program { static void Main(string[] args) { Derivata obiect2 = new Derivata().Text. Exemplul 97: using using using using System. } } class Derivata : Baza { public new void Afis() // !!! new { Console.

Afis(). Derivata2 obiect3 = new Derivata2().Afis().7.Collections. clasa derivata\n").Generic.WriteLine("Apelul functiei Afis din } } class Derivata : Baza { sealed override public void Afis() { Console. } } } 132 clasa de baza\n"). obiect2. În acest fel ea nu mai poate fi suprascrisă într-o clasă derivată Exemplul 98: using System.I.Afis(). Metoda sealed O metodă având tipul override poate fi declarată sealed. namespace Exemplul_98 { class Baza { public virtual void Afis() { Console. using System. using System. obiect1. !!! clasa Derivata2\n").9. Baza obiect1 = new Derivata().WriteLine("Apelul functiei Afis din } } class Program { static void Main(string[] args) { Derivata obiect2 = new Derivata(). obiect3.WriteLine("Apelul functiei Afis din } } class Derivata2 : Derivata { override public void Afis() //!!! EROARE { Console.Text. //(1) //(2) .

ci presupune în principal stabilirea unor decizii arhitecturale. va împiedică suprascrierea acestei metode în clasa Derivata2. decizii ce au la bază unul dintre modelele arhitecturale de bază. să definim „template”-ul. Consistenţa: Ferestrele şi controalele trebuie să fie afişate după un design asemănător („template”) pe parcursul utilizării aplicaţiei. când un utilizator trebuie să introducă nişte informaţii – unele obligatorii şi altele opţionale – este indicat să organizăm controalele astfel încât primele să fie cele care preiau informaţii obligatorii. clic.) Realizarea unei aplicaţii vizuale nu constă doar în desenare şi aranjare de controale. Această operare are ca efect scrierea automată a unor secvenţe de program.Va genera eroare.    133 . trebuie decidem cum va arăta aceasta. secvenţe care. este vitală culegerea de informaţii despre utilizatorii finali ai aplicaţiei şi a modului în care aceştia sunt obişnuiţi să lucreze. Astfel. II. Înainte de a implementa interfaţa. din clasa Derivata. În acest sens. Programare vizuală II. deoarece modificatorul sealed al metodei Afis(). Poziţia controalelor: Locaţia controalelor dintr-o fereastră trebuie să reflecte importanţa relativă şi frecvenţa de utilizare. Estetica: Interfaţa trebuie să fie pe cât posibil plăcută şi atrăgătoare. În realizarea aplicaţiei mai trebuie respectate şi principiile proiectării interfeţelor:  Simplitatea: Interfaţa trebuie să fie cât mai uşor de înţeles şi de învăţat de către utilizator şi să permită acestuia să efectueze operaţiile dorite în timp cât mai scurt.1. Concepte de bază ale programării vizuale Programarea vizuală trebuie privită ca un mod de proiectare a unui program prin operare directă asupra unui set de elemente grafice (de aici vine denumirea de programare vizuală). hint etc. Spunem că o aplicaţie este vizuală dacă dispune de o interfaţă grafică sugestivă şi pune la dispoziţia utilizatorului instrumente specifice de utilizare (drag. împreună cu secvenţele scrise textual vor forma programul.

Codul „din spatele” unei componente vizuale este accesibil în modul Code (F7).2. O aplicaţie Windows conţine cel puţin o fereastră (Form) în care se poate crea o interfaţă cu utilizatorul aplicaţiei.cs este formularul creat implicit ca parte a proiectului. rapid şi uşor. Fişierul Form1. În fereastra Solution Explorer sunt afişate toate fişierele pe care Microsoft Visual C# 2008 Express Edition le-a inclus în proiect. Form1. Pentru a construi o aplicaţie Windows (FileNew Project) se selectează ca template Windows Forms Application.cs conţine un formular (fereastra Form1 derivata din clasa Form) care este reprezentată în cadrul din dreamt în formatul Design (Form1. Componentele vizuale ale aplicaţiei pot fi prelucrate în modul Designer (Shift+F7) pentru a plasa noi obiecte.cs[Design]. adică într-un format in 134 . Mediul de dezvoltare Visual C# (prezentarea interfeţei) Mediul de dezvoltare Microsoft Visual C# dispune de instrumente specializate de proiectare. a le stabili proprietăţile etc.II. ceea ce permite crearea aplicaţiilor în mod interactiv.

.Run(new Form1()). Ferestrele care sunt afişate in fereastra principală se pot stabili prin selecţie din meniul View.P) este utilizată pentru a schimba proprietăţile obiectelor.cs poate fi văzut ca fişier text sursă prin selectarea lui în fereastra Solution Explorer.X) conţine controale standard drag-and-drop şi componente utilizate în crearea aplicaţiei Windows. punând la dispoziţie proprietăţi pentru a obţine informaţii despre aplicaţie. Metoda Run creează un formular implicit. prin inserarea controalelor necesare selectate din fereastra Toolbox. Fereastra Properties (Ctrl+W. metode de lucru cu aplicaţia şi altele. Fişierul Form1. La crearea unei noi aplicaţii vizuale. Microsoft Visual C# 2008 Express Edition generează un spaţiu de nume care conţine clasa statică Program. aplicaţia răspunzând la mesajele utilizatorului până când formularul va fi închis. clic dreapta cu mouse-ul şi selecţia opţiunii View Code. Toolbox (Ctrl+W. uzuală fiind Build Solution (F6). 135 . Clasa Application este responsabilă cu administrarea unei aplicaţii Windows. cu metoda statică ce constituie punctul de intrare (de lansare) a aplicaţiei: static void Main() { } . Controalele sunt grupate în categoriile logice din imaginea alăturată. care se activează atunci când este „atinsă” cu mouse-ul. Application.care se poate executa proiectare vizuală.. Compilarea modulelor aplicaţiei şi asamblarea lor într-un singur fişier „executabil” se realizează cu ajutorul opţiunilor din meniul Build. Toate metodele şi proprietăţile clasei Application sunt statice.

Elementele POO în context vizual În cele ce urmează pentru explicaţiile care vor avea loc vom considera o aplicaţie Windows numită Test: În urma generării proiectului Test avem: 136 . urmărirea până la puncte de întrerupere etc.Odată implementată. Proiectarea vizuală a formularului se poate face inserând controale selectate din fereastra de instrumente (Toolbox) şi setând proprietăţile acestora.3. aplicaţia poate fi lansată. Ferestre auxiliare de urmărire sunt vizualizate automat în timpul procesului de depanare. II. Alte facilităţi de depanare pot fi folosite prin umărirea pas cu pas. cu asistenţă de depanare sau nu (opţiunile Start din meniul Debug). (celelalte opţiuni ale meniului Debug). sau pot fi activate din submeniul Windows al meniului Debug.

Orice fereastră poate fi aranjată într-o poziţie dorită de utilizator. În acest proces veţi fi ghidat de săgeţile 137 fereastra se închide. În caz contrar sau stângă a mediului de programare. care. Pentru aceasta dăm clic pe una dintre barele de titlu ale ferestrelor menţionale mai sus (Solution Explorer. retrăgându-se în partea dreaptă .Fereastra Toolbox Fereastra Windows Forms Designer în care s-a creat Form1 Fereastra Solution Explorer Fereastra pentru afişarearea Listei de erori Bara de unelte Fereastra Properties Bara de meniuri Toate ferestrele. au în partea dreaptă o piuneză. Toolbox sau Error List) si o deplasăm în poziţia dorită. Properties. dacă este în poziţie verticală fixeză fereastra deschisă.

De preferat ar fi ca aceste ferestre să rămână în poziţiile lor implicite. la crearea unui proiect windows.care apar central şi pe margini. Barele de instrumente Implicit. apar două bare de instrumente Prima bară de unelte unde: Icoana Semnificaţie proiect nou (Ctrl+Shift+A) 138 .

Icoana Semnificaţie adăugare de noi itemi (Ctrl+Shift+A) deschide fişier (Ctrl+O) salvează Form1.cs (Ctrl+S) salvează tot proiectul (Ctrl+Shift+O) cut (Ctrl+X) copy (Ctrl+C) paste (Ctrl+V) undo (un pas înapoi) (Ctrl+Z) redo (un pas înainte) (Ctrl + Y) navigare înapoi în cod sau ferestre (Ctrl + -) navigare înainte în cod sau ferestre (Ctrl + Shift -) Start debugging (F5) Compilează proiectul şi-l lansează în modul debug Solution Configuration Solution Platform căutare şi înlocuire (Ctrl + Shift + F) 139 .

Putem să deschidem una dintre opţiunile din fereastră apăsând semnul plus din faţă. Orice control poate fi adus pe Form-ul nostru (îi vom putea spune. şi anume pentru: alinieri. Icoanele aflate pe această bară sunt deosebit de sugestive pentru acţiunea pe care o realizează. 140 . U) A doua bară de instrumente se foloseşte atunci când dorim să acţionăm asupra mai multor controale din fereastra noastră. fereastră. Fereastra Toolbox Revenind la fereastra Toolbox.Icoana Semnificaţie fereastra pentru căutare fereastra Solution Explorer (Ctrl + W. redimensionări. sau prin drag and drop în Form. P) fereastra Object Browser (Ctrl + W. dacă deschidem Common Controls în fereastră apar controale mai des folosite. interfaţă. De exemplu. aducerea în faţă/spate a unora dintre controalele existente. X) fereastra de start Start Page fereastra Document Outline (Ctrl + W. J) fereastra Toolbox (Ctrl + W. S) fereastra Properties (Ctrl + W. spaţieri. formular) prin dublu clic pe respectivul control. în egală măsură.

În cazul în care fereastra Designer este închisă. din partea dreaptă se referă.Control. Cele mai multe controale sunt obiecte acestui 141 de fapt clase multe derivate dintre din clasa şi System. Fereastra Solution Explorer. se va acţiona butonul din dreapta al mouse-ului.cs.Windows. pentru a obţine efectul afişat şi în imagini. vom discuta. în unele dindre exemplele are urmează Fereastra Properties Aminteam mai sus că în Toolbox există toate tipurile de controale care îi sunt necesare unui programator pentru a realiza o aplicaţie. fereastra din dreapta. Despre opţiunile care apar în cazul în care dăm clic dreapta pe Test. la modul concret. În toate cazurile menţionate mai sus.Forms. Acelaşi Properties.Fereastra Solution Explorer Vom observa că în momentul în care dăm clic pe Form sau pe un control. se va referi la acesta control sau această fereastră. printre altele la ferestra Designer sau la fereastra în care utilizatorul va scrie propriul cod. iar în fereastra principală se va lucru deschide. apăsăm pe opţiunea View Code. din aceeaşi fereastră. Datorită proprietăţile . putem apela la opţiunea Open şi va reapărea în fereastra centrală. Properties. Dacă dorim să vedem codul. îl putem încă spune o şi ferestră despre corespunzătoare codului dorit.

printr-o secvenţă de cod sau alta. să sesizeze acţiunea utilizatorului asupra respectivelor controale. proprietăţi furnizate de către clasa Control: Proprietatea Anchor BackColor Bottom Dock Enabled ForeColor Height Left Name Parent Right TabIndex TabStop Tag Top Visible Width Descrierea proprietăţii se referă la posibilitatea de a ancora controlul faţă de o margine (sau toate) permite stabilirea culorii de fundal a controlului permite stabilirea distanţei dintre marginea de sus a ferestrei şi control ataşează controlul la una dintre marginile ferestrei permite controlului să recepţioneze evenimente de la utilizator permite stabilirea culorii textului permite definirea înălţimii controlului permite stabilirea distanţei dintre marginea din stânga a ferestrei şi marginea stânga a controlului permite denumirea controlului pentru a-l putea mai uşor vizualiza şi manipula în codul sursă părintele controlului permite stabilirea distanţei dintre marginea din dreapta a ferestrei şi marginea din dreapta a controlului prin numărul de ordine care i se ataşează se stabileşte ordinea activării controlului la apăsarea tastei TAB permite sau nu ca respectivul control să fie activat prin apăsarea tastei TAB se referă la un şir de caractere pe care controlul îl poate stoca în interiorul său permite stabilirea distanţei dintre marginea de sus a ferestrei şi marginea de sus a controlului stabileşte dacă respectivul control. implementează Evenimentul Clic DoubleClic DragDrop Descrierea evenimentului se generează când se dă clic asupra unui control se generează când se dă dublu clic asupra unui control. deoarece controlul acţionează la primul clic se genereazăla finalizarea lui drag and drop 142 . comune controalelor. Vom vedea.evenimentele diverselor controale vor fi identice. prin intermediul controalelor. în aplicaţiile care urmează. care exită în fereastră. este (TRUE) sau nu vizibil stabileşte lăţimea controlului Proprietăţile controalelor. din interfaţa mediului de programare. Excepţie făcând Button asupra căruia nu se va putea face dublu clic. Fereastra Properties. şi o serie de evenimente la care controalele vor reacţiona: În funcţie de tipul acţiunii vor reacţiona. vom observa că va conţine atât proprietăţile cât şi evenimentele ataşate controalelor. Tabelul de mai jos prezintă proprietăţile Aplicaţiile pe care le creăm trebuie să fie capabile. sunt moştenite sau supraînscrise din clasa de bază Control. că exită clase care definesc controale şi care pot fi clase de bază pentru alte controale. Tot clasa Control amintită mai sus.

Forms.4. generat automat pe măsură ce noi desemnăm componentele şi comportamentul acesteia. Se generează după KeyDown şi înainte de KeyUp se generează când o tastă este eliberată în timp ce controlul este activ. acest cod realizează: derivarea unei clase proprii din System. elemente specifice (controale) cum ar fi butoane (System.Form). Se generează după terminarea evenimentului Validating. printr-un drag and drop.Windows. indicând faptul că validarea controlului este completă se generează când un control este pe cale să devină activ II. printr-un drag and drop.Forms. În fapt. Se va furniza codul ASCII al tastei apăsate. Se va furniza codul de scanare al tastei apăsate. Ferestre Spaţiul Forms ne oferă clase specializate pentru: creare de ferestre sau formulare (System. ajunge în interiorul controlului se generează atunci când obiectul. MenuStrip.1.4. Se generează înainte de evenimentele KeyPress şi KeyUp se generează atunci când o tastă este apăsată în timp ce controlul este activ. 143 .Forms.Form.Windows.Evenimentul DragEnter DragLeave DragOver KeyDown KeyPress KeyUp GotFocus LostFocus MouseDown MouseMove MouseUp Paint Validated Validating Descrierea evenimentului se generează atunci când obiectul.Forms. Timer etc.Windows. Constructorul ferestrei realizează instanţieri ale claselor Button.Button). ajunge deasupra controlului se generează atunci când o tastă este apăsată în timp ce controlul este activ. clasă care este înzestrată cu o colecţie de controale (iniţial vidă). Se generează după KeyDown şi KeyPress se generează când controlul devine activ (se mai spune: când controlul primeşte input focusul) se generează când controlul devine inactiv (se mai spune: când controlul pierde input focusul) se generează când cursorul mouse-ului este deasupra controlului şi se apasă un buton al mouse-ului se generează când trecem cu mouse-ul deasupra controlului se geerează când mouse-ul este deasupra controlului şi eliberăm un buton al mouse-ului se generează la desenarea controlului se generează când un control este pe cale să devină activ. casete de text (System.Windows. Proiectarea unei ferestre are la bază un cod complex.TextBox) etc. printr-un drag and drop. ajunge să părăsească controlului se generează atunci când obiectul. (orice plasăm noi în fereastră) şi adaugă referinţele acestor obiecte la colecţia de controale ale ferestrei. Construirea interfeţei utilizator II.

acesta stabilinduse direct : public Form Owner { get. Activarea propietarului unui formular deschis modal va determina activarea formularului deschis modal. form. Click etc.Hide(). Când un nou formular este activat folosind form.) şi o serie de metode specifice (handlere) de tratare a evenimentelor (Load. F_nou form = new F_nou(). } F_nou form=new F_nou(). metoda a doua permiţând ca revenirea în fereastra din care a fost activat noul formular să se facă numai după ce noul formular a fost închis (spunem că formularul nou este deschis modal). Focus etc. culoare de fundal. O fereastră poate fi activată cu form. Vizibilitatea unui formular poate fi setată folosind metodele Hide sau Show. // setarea propietatii Visible indirect sau this. set. atunci ea este instanţiată automat în programul principal (metoda Main). Deţinătorul se poate stabili setând proprietarul înainte să apelăm Form. form.ShowDialog() sau apelând From. Dacă nu.ShowDialog() cu proprietarul ca argument.). Clasele derivate din Form moştenesc o serie de proprietăţi care determină atributele vizuale ale ferestrei (stilul marginilor. form. metode care implementează anumite comportamente (Show.Owner = this. Un propietar este o fereastră care contribuie la comportarea formularului deţinut.ShowDialog(this).Show(). etc. // setarea propietatii Visible direct 144 .Dacă modelul de fereastră reprezintă ferestra principală a aplicaţiei.ShowDialog().Show() nu va avea nici un deţinător.).Show() sau cu form. Pentru a ascunde un formular putem folosi : this. Hide.Visible = false. Formularul deschis modal va avea un proprietar setat pe null. trebuie să scriem noi codul care realizează instanţierea.

}   ControlBox precizează dacă fereastra conţine sau nu un icon. centrat pe formularul care l-a afişat (CenterParent) atunci când formularul va fi afişat modal.Y) reprezintă coordonatele colţului din stânga sus al formularului relativ la colţul stânga sus al containerului. EventArgs e) { this. Partea care este desenată de formular mai este denumită şi Client Area.MaxValue.  HelpButton-precizează dacă butonul va apărea sau nu lângă butonul de închidere al formularului (doar dacă MaximizeBox=false.Minimize. this.MaximumSize = new Size(int. acesta se va redimensiona automat... Marginile.Move.Maximize.Size. Mişcarea formularului ( şi implicit schimbarea locaţiei) poate fi tratată în evenimentele Move şi LocationChanged .   Location (X. stabilită de Windows. 1).. această redimensionare fiind tratată în evenimentele Resize sau in SizeChanged. EventArgs e) { this. MinimizeBox=false).. 1). Când se schimbă propietăţile Width şi Height ale unui formular.   Icon reprezintă un obiect de tip *. MaximizeBox şi MinimizeBox precizează dacă fereastra are sau nu butonul Maximize şi respectiv Minimize Opacity indică procentul de opacitate  145 .ico folosit ca icon pentru formular. butonul de închidere al ferestrei şi meniul System (Restore. (Această propietate e ignorată dacă StartPosition = Manual). Chiar dacă propietatea Size a formularului indică dimensiunea ferestrei.MinimumSize = new Size(200. titlul şi scrollbar-ul sunt desenate de Windows. } //formularul in desktop   Size (Width şi Height) reprezintă dimensiunea ferestrei. Dacă utilizatorul apasă acest buton şi apoi apasă oriunde pe formular va apărea evenimentul HelpRequested (F1). void Form_Load(object sender. sau poate fi sau Windows-ul va centrată pe desktop (CenterScreen). 100). 100).. Poziţia poate fi setată Manual. dimensiunea iniţială şi locaţia pentru formular formularul având dimensiunile şi locaţia stabilite de programator (WindowsDefaultLocation) stabili (WindowsDefaultBounds) sau. this.. reamintim: StartPosition determină poziţia ferestrei atunci când aceasta apare prima dată.Printre cele mai uzuale proprietăţi ale form-urilor.DesktopLocation = new Point(1. MaxinumSize şi MinimumSize sunt utilizate pentru a restricţiona dimensiunile unui formular.Close).Location = new Point(1. formularul nu este în totalitate responsabil pentru desenarea întregului conţinut al său. Locaţia formularului poate fi stabilită relativ la desktop astfel: void Form_Load(object sender.

ci efectuăm dublu clic în căsuţa respectivă. Activated apare pentru formularul activ.). se generează automat un nume pentru această funcţie. Acesta poate fi „găzduit” de un container ce poate fi un formular sau un alt control. Aceste controale pot fi grupate astfel: 146 . Dacă nu scriem nici un nume pentru funcţia de tratare. pentru TextBox este TextChanged. se va genera automat o funcţie de tratare pentru evenimentul implicit asociat controlului (pentru un buton evenimentul implicit este Clic. pentru un formular Load etc. ţinând cont de numele controlului şi de numele evenimentului (de exemplu button1_Click).4.  SizeGripStyle specifică tipul pentru ‘Size Grip’ (Auto. TopMost precizează dacă fereastra este afisată în faţa tuturor celorlalte ferestre. Dacă în Designer efectuăm dublu clic pe un control. ShowInTaskbar precizează dacă fereastra apare in TaskBar atunci când formularul este minimizat.NET vine cu o serie de controale standard. Size grip dreapta jos) indică faptul că această fereastră poate fi redimensionată. TransparencyKey identifică o culoare care va deveni transparentă pe formă. (în colţul din   Definirea unei funcţii de tratare a unui eveniment asociat controlului se realizează prin selectarea grupului mentului dorit. Controale Unitatea de bază a unei interfeţe Windows o reprezintă un control. FormClosing apare când formularul se va inchide ca rezultat al acţiunii utilizatorului asupra butonului Close (Dacă se setează CancelEventArgs. Un control este o instanţă a unei clase derivate din System.Windows. Hide).Cancel =True atunci se va opri închiderea formularului).2. disponibile în Toolbox. Deactivate apare atunci când utilizatorul va da clic pe alt formular al aplicatiei. Visual Studio . FormClosed apare când formularul este închis. Printre evenimentele cele mai des utilizate.Forms şi este reponsabil cu desenarea unei părţi din container. se numără :    Events din ferestra Properties a controlului respectiv şi alegerea eveni- Load apare când formularul este pentru prima data încărcat în memorie. Show.   II.

Cu ajutorul metodei Drag and drop plasaţi pe formular un buton pe care veţi introduce textul START.5. două controale TextBox. Este folosit pentru adăugarea imaginilor sau a altor resurse de tip bitmap.1. Acest exemplu afişează numerele pare din intervalul [0. Afişează o listă de articole din care utilizatorul poate alege. mutarea sau redimensionarea unui control. Controlul form este un container. Aplicaţii Numere pare II.n) unde n este o variabilă globală a cărei valoare este introdusă de la tastatură. putem personaliza programul nostru.Controale form.5. În tabelul de mai jos veţi găsi o listă cu controalele cel mai des folosite şi cu descrierea lor. Folosind proprietăţile. metodele şi evenimentele unui formular. două controale label pe care veţi introduce textele din exemplul de mai jos 147 . şi a pentru a eticheta controalele. Funcţia controlului buton calendar casetă de validare etichetă casetă cu listă imagine pointer buton radio Numele controlului Button MonthCalendar CheckBox Label ListBox PictureBox Pointer RadioButton Descriere Sunt folosite pentru a executa o secvenţă de instrucţiuni în momentul activării lor de către utilizator Afişează implicit un mic calendar al lunii curente. Este utilizat pentru selectarea. Se deschide o aplicaţie Windows Forms pe care o veţi denumi Numere pare. casetă de text TextBox II. Din fereastra Properties modificaţi numele formularului. Este utilizat pentru afişarea textului generat de o aplicaţie sau pentru a primi datele introduse de la tastatură de către utilizator. Stabiliţi dimensiunea formularului şi culoarea de fond alegând una dintre cele predefinite din opţiunea BackColor. Scopul său este de a găzdui alte controale. Acesta poate fi derulat şi înainte şi înapoi la celelalte luni calendaristice. Oferă utilizatorului opţiunile : da/nu sau include/exclude Sunt folosite pentru afişarea etichetelor de text. Exemple de folosire a acestor controale vor urma după explicarea proprietăţilor comune al controalelor şi formularelor. Este folosit pentru ca utilizatorul să selecteze un singur element dint-un grup de selecţii.

for (.i<n.Text + " " + Convert. } } În fereastra Solution Explorer executaţi dublu clic pe Form1. private System. private System.Windows.Forms.Windows.Forms.Label label2.TextBox textBox1.Forms.TextBox textBox2.Text). EventArgs e) { n = Convert. în zona de declaraţii a funcţiei InitializeComponent().Forms.Windows.Text = textBox2.Executaţi dublu clic pe butonul START şi editaţi codul sursă conform exemplului de mai jos: private void button1_Click(object sender. private System.Designer.ToString(i). 148 . În acest moment aplicaţia este gata.Button button1.Forms.Windows.n.Label label1. Din meniul File alegeţi opţiunea Save All şi rulaţi aplicaţia. int i=0. private System.cs pentru a declara variabilele globale n şi i.Windows.ToInt32(textBox1.i=i+2) { textBox2. private System.

iar cea de a doua setează culoarea formularului. Încercaţi să vedeţi cum se modifică setând proprietatea la Fixed3D (tot din fereastra Properties). la mai multe linii. this. Pentru a realiza acest lucru trageţi un TextBox într-un formular şi modificaţi valoarea proprietăţii Multiline din panoul Properties de la False la true. public Form1(){ InitializeComponent(). Controlează stilul bordurii unui formular.Text = "Primul formular".  Proprietatea BorderStyle. pentru a-i cuprinde întreg conţinutul.  Proprietatea AutoCheck când are valoarea true. 149 . Toate acestea le puteţi modifica după preferinţe din fereastra Properties.5.  Proprietatea Multiline schimbă setarea implicită a controlului TextBox de la o singură linie. introducând o declaraţie în codul programului. Proprietăţi comune ale controalelor şi formularelor:  Proprietatea Text Această proprietate poate fi setată în timpul proiectării din fereastra Properties.  Proprietatea FormatString vă permite să setaţi un format comun de afişare pentru toate obiectele din cadrul unei ListBox.2. decide dacă un control este redimensionat automat.II. Prima proprietate enunţată setează culoare textului din formular. }  Proprietăţile ForeColor şi BackColor. sau programatic.  Proprietatea AutoSize folosită la controalele Label şi Picture. Aceasta se găseşte disponibilă în panoul Properties. un buton radio îşi va schimba starea automat la executarea unui clic.

Proprietatea TabIndex setează sau returnează poziţia controlului în cadrul aranjării taburilor. } Numele metodei button1_Clic este alcătuit din numele controlului button1. EventArgs e) { this. Metode şi evenimente Un eveniment este un mesaj trimis de un obiect atunci când are loc o anumită acţiune.Close(). urmat de numele evenimentului: Clic. Introduceţi acum în el linia de cod this.Close(). Pentru a reuşi acest lucru folosim metodele Show() şi Close() ale controlului. Evenimentul Click Când dezvoltăm programe pentru Windows. Proprietatea ImageAlign specifică alinierea unei imagini aşezate pe suprafaţa controlului. uneori trebuie să afişăm ferestre adiţionale.      Proprietatea Enabled determină dacă un control este sau nu activat într-un formular. De asemenea trebuie să le facem să dispară de pe ecran. pentru a afişa administratorul său de evenimente.3. o selecţie de meniu. Proprietatea Width and Height permite setarea înălţimii şi a lăţimii controlului. orice ce se intamplă în sistem şi trebuie să primească un raspuns din partea programului. pe scurt. Proprietatea Font determină fontul folosit într-un formular sau control.5. Evenimentele sunt proprietăţi ale clasei care le publică. Trageţi un buton în Form2 şi executaţi dublu clic pe buton. private void button1_Click(object sender. Metodele Show() şi Close(). Un eveniment (event) poate fi apăsarea unui buton. Cel mai important eveniment pentru Button este Clic (desemnând acţiunea clic stânga pe buton). trageţi un control de tip Button pe formular. Din meniul Project selectaţi Add Windows Form. pentru noul formular creat. Exemplul 2: Deschidere şi închidere de formulare Deschideţi o nouă aplicaţie Windows Forms. trecerea unui anumit interval de timp. Această actiune poate fi: interacţiunea cu utilizatorul (mouse click) sau interacţiunea cu alte entităţi de program.. În acest moment aţi inclus în program două formulare. Cuvantul-cheie event contolează cum sunt accesate aceste proprietăţi. Proprietatea Visible setează vizibilitatea controlului. II. 150 . iar în caseta de dialog care apare adăugaţi numele Form2.

Va trebui sa aveţi două imagini diferite salvate într-un folder pe calculatorul vostru. } În acest moment rulaţi programul apăsând tasta F5 şi veţi observa că la executarea unui clic pe butonul din Form1 se deschide Form2 iar la executarea unui clic pe butonul din Form2 acesta se închide. Editaţi administratorul evenimentului conform exemplului de mai jos: private void button1_Click(object sender. un control de tip PictureBox şi un control de tip Label pe care scrieţi textul: Te crezi inteligent?. Textul pentru fiecare control îl veţi introduce utilizând proprietatea Text. trageţi două controale de tip Button pe formular pe care le redenumiţi cu DA şi cu NU.Acum ar trebui să reveniţi la Form1 şi executaţi dublu clic pe butonul din acest formular pentru a ajunge la administratorul său de evenimente. Executaţi dublu clic pe butonul DA şi folosiţi următorul cod pentru administratorul evenimentului Clic: 151 . EventArgs e) { Form2 form2 = new Form2(). Exemplul 3: Imagini Deschideţi o nouă aplicaţie Windows Forms.form2.Show().

private void button1_Click(object sender. Executaţi dublu clic pe butonul NU şi folosiţi următorul cod pentru administratorul evenimentului Clic: private void button2_Click(object sender.Visible = true. Deschideţi o nouă aplicaţie Windows Forms. Modificaţi codul sursă al controlului Button.gif").Visible = true.Image = Image. în funcţie de butonul apăsat.NET". conform exemplului de mai jos. Trageţi un control de tip Button pe formular şi un control de tip TextBox. } Veţi obţine la rularea aplicaţiei afişarea uneia din cele două imagini.Image = Image. şi executaţi dublu clic pe el.} În acest moment rulaţi programul apăsând tasta F5 şi faceţi clic pe buton.FromFile("C:\\Imagini \\line.} Va trebui să completaţi corect calea spre folder-ul în care aţi salvat imaginea pentru importul cu succes al ei. în momentul în care se execută clic pe un buton.private void button1_Click(object sender.FromFile("C:\\Imagini\\rat. conform imaginii.gif"). pentru a ajunge la administratorul său de evenimente. oferim acum un exemplu de afişare într-un TextBox a unui mesaj. EventArgs e) { pictureBox1.textBox1. sau Exemplul 4: Casetă de text Tot în cadrul evenimentului Clic. Modificaţi textul ce apare pe buton. EventArgs e) {pictureBox1.Text = a. pictureBox1. 152 . EventArgs e) {string a = "PLATFORMA . pictureBox1.

153 .Exemplul 5: Casetă de mesaj Pentru a crea o casetă mesaj. trageţi un control de tip Button în formular. Unchecked. Soluţia unei probleme cu mai multe variante de răspuns este memorată cu ajutorul unor checkbox-uri cu proprietatea ThreeState. În acest caz. Apăsarea butonului Verifică determină afişarea unei etichete şi a butoanelor radio DA şi NU. trebuie verificată propietatea CheckState(Checked.Într-o nouă aplicaţie Windows Forms. Apoi rulaţi aplicaţia. atunci se schimbă funcţionalitatea acestor controale.Show("ti-am spus"). Răspunsul este afişat într-un MessageBox. Indeterminate) pentru a vedea starea controlului CheckBox. apelăm metoda MessageBox.. Exemplul 6: Este un exemplu de utilizare a Propietatea Checked controalelor de selecţie CheckBox şi RadioButton. Dacă proprietatea ThreeState este setată. indică dacă am selectat controlul. în sensul că acestea vor permite setarea unei alte stări. executaţi dublu clic pe buton şi adăugaţi în administratorul evenimentului Clic linia de program: MessageBox.Show().. modificaţi textul butonului cum doriţi sau ca în imaginea alăturată „va apare un mesaj”.

un control de tip Button..Checked=false. plasaţi pe formular şi un control de tip TextBox.Visible=false.radioButton2.EventArgs e) {label2. şi un control de tip Timer pentru care setaţi intervalul la 50.CheckState==CheckState. radioButton1.Show("CORECT").CheckState==CheckState.Checked && checkBox2. stabiliţi culoarea de fond a formularului alegând una dintre cele predefinite din opţiunea BackColor. Stabiliţi dimensiunea formularului la 740 cu 540.. radioButton2.EventArgs e){ if (checkBox1.Unchecked) MessageBox. System. } Exemplul 7: Construcţia Fractalului Se deschide o aplicaţie Windows Forms pe care o veţi denumi Fractal.").Visible=false. radioButton2. else MessageBox. label2.CheckState==CheckState. Cu ajutorul metodei Drag and drop plasaţi pe formular: două controale de tip Label în care veţi introduce următoarele texte „Construirea unui fractal” (pentru eticheta poziţionată în partea de sus a formularului) şi „Introduceţi numărul de pătrate” (pentru cea de a doua etichetă pe care e bine să o poziţionaţi la o distanţă nu prea mare de prima).După adăugarea controalelor pe formular şi setarea proprietăţilor Text şi ThreeState în cazul checkbox-urilor stabilim evenimentele clic pentru butonul Verifica şi pentru butonul radio cu eticheta DA: private void radioButton1_Click(object sender.. 154 .Visible=true. System. radioButton1.Visible=true.CheckState==CheckState.Checked && checkBox3.radioButton1.Visible=true.} private void button1_Click(object sender.Visible=false.Checked && checkBox5.Checked=false.CheckState==CheckState.Show("Indicatie> Daca punem un sac in altul.Checked && checkBox4.

p[2]. int l) { int l2 = l / 2. y + l3.Y = y + l.l4. EventArgs e) { m = 1. y .l4. } În aceeaşi fereastră de cod scriem funcţia recursivă patrat care va genera fractalul. } Graphics graph = this. if (n > 1) { patrat(n .1. p).X = x + l.CreateGraphics().Start(). int l4 = l / 4.1. patrat(n . p[0]. patrat(n .l4. int x. p[1]. x . x + l3. timer1. Pen penc. p[3].Y = y + l. Point[] p = new Point[4]. l2). l2). else penc = new Pen(Color. y .Y = y. l2).DrawPolygon(penc. void patrat(int n.X = x.BlueViolet). private void button1_Click(object sender. În funcţia button1_Clic iniţializăm variabila m cu valoarea 1 şi pornim timer-ul. int y. int l3 = l2 + l4.X = x + l.Executând dublu clic pe butonul Start va fi deschis codul sursă.l4. if (n % 2 == 0) penc = new Pen(Color.1. p[3]. graph. } 155 .1. x . p[2]. p[1]. l2). patrat(n . p[0].X = x. x + l3. y + l3.Y = y.Red).

Designer.Timer timer1. Evenimentul MouseEnter. m = m + 1. private System. EventArgs e) { if (m <= Convert. private void timer1_Tick(object sender.Forms.Text)) { int x = 300. private System.Windows.Label label2.Windows. y = 300.Windows.Forms. Exemplul 8: Casete de dialog 156 .cs pentru a declara variabila globală m.Windows.Label label1. private System. patrat(m. int m. x.ToInt32(textBox1.Se execută acum dublu clic pe obiectul timer de pe formular pentru a completa funcţia timer1_Tick cu apelul funcţiei recursive patrat.TextBox textBox1.Forms. în zona de declaraţii a funcţiei InitializeComponent(). private System. Din meniul File alegeţi opţiunea Save All şi rulaţi aplicaţia. private System.Forms. } } În fereastra Solution Explorer executaţi dublu clic pe Form1. În acest moment aplicaţia este gata. l).Windows. y. Metodele ShowDialog() şi Clear(). l = 150.Button button1.Forms.

cs şi modificaţi linia de program: this. setaţi proprietatea Text la “casetă de dialog”. if (v.textBox1.Designer. apoi trageţi un buton în formular şi setaţi proprietatea Text a butonului la : „să avem un dialog”. Creaţi un alt formular la acest proiect (alegeţi Add Windows Forms din meniul Project).DialogResult != DialogResult.button1. EventArgs e) {Form2 v = new Form2(). setaţi proprietatea Text a butonului din stânga la “OK” iar al celui din dreapta la “Cancel”.Text. adăugaţi un control TextBox în formular. }} 157 . iar apoi executaţi dublu clic pe buton şi modificaţi numele metodei din button1_click în button1_MouseEnter apoi folosiţi următorul cod pentru administratorul evenimentului MouseEnter.EventHandler(this.Close(). Acum executaţi dublu clic pe butonul OK şi folosiţi următorul cod pentru administratorul evenimentului Clic: private void button1_Click(object sender. EventArgs e) {textBoxText = textBox1.} Executaţi dublu clic pe butonul Cancel şi folosiţi următorul cod pentru administratorul evenimentului Clic: private void button2_Click(object sender. trageţi în formular un control de tip Label şi setaţi proprietatea Text la “scrie text”.this. Acest eveniment al controlului Button vă permite ca la o simplă plimbare pe buton fără a executa clic pe el. } Intraţi în codul sursă pentru Form1.MouseEnter += new System. astfel: this. EventArgs e) { Form2 w = new Form2(). v. w.ShowDialog(). private void button1_MouseEnter(object sender.Creaţi o nouă aplicaţie Windows Forms.button1_MouseEnter).button1.OK){ this.Click += new System.button1_Click).EventHandler(this.Clear(). executaţi clic pe formularul casetei de dialog şi setaţi proprietatea AcceptButton la button1 iar proprietatea CancelButton la button2.ShowDialog(). setaţi proprietatea DialogResult a butonului din stanga la OK iar al celui din dreapta la Cancel. să se execute codul sursă al metodei. apoi în ordine: setaţi proprietatea ControlBox la valoarea false. adăugaţi două controale de tip Button.

Evenimentul MouseLeave. iar la sfărşitul clasei Form2 adăugaţi proprietatea: public string TextBoxText {get{ return(textBoxText). Metoda Start(). Se deschide o aplicaţie Windows Forms pe care o veţi denumi Schimbă culoarea. un control de tip Button pe care veţi introduce textul STOP. un control de tip Label pe care veţi introduce textul Schimbă culoarea. Stabiliţi dimensiunea formularului şi culoarea de fond alegând una dintre cele predefinite din opţiunea BackColor. Din fereastra Properties redenumiţi formularul. 158 . un control de tip Timer.} Acum puteţi rula acest program.La începutul clasei Form2 adăugaţi declaraţia: public string textBoxText. Cu ajutorul metodei Drag and drop plasaţi pe formular: un control de tip Button pe care veţi introduce textul START. Exemplul 9: Schimbă culoarea În acest exemplu este prezentată modalitatea de schimbare aleatoare a culorii unei etichete.

EventArgs e) {label1. Evenimentul MouseLeave va permite executarea codului sursă a metodei în momentul în care veţi plimba mouse-ul pe deasupra imaginii butonului şi nu la executarea clic-ului.} Intraţi în codul sursă pentru Form1.EventHandler(this.Designer. Declaraţi următoarea variabilă ca fiind variabilă locală pentru clasa Form1 Random r = new Random(200). 159 .Next(255).MouseLeave += new System.Stop().button1_Click).button1_MouseLeave).cs şi modificaţi linia de program: this. Din meniul File alegeţi opţiunea Save All şi rulaţi aplicaţia.button1.button1. r.Next(255)). astfel: this.} În acest moment aplicaţia este gata. EventArgs e) {timer1.Executaţi dublu clic pe butonul START şi editaţi administratorul evenimentului conform exemplului de mai jos: private void button1_MouseLeave(object sender. r.FromArgb(r.Next(255).BackColor = Color.EventHandler(this. Executaţi dublu clic pe controlul Timer şi inseraţi linia de cod care va permite schimbarea aleatoare a culorilor pentru controlul Label conform exemplului de mai jos: private void timer1_Tick(object sender. Executaţi dublu clic pe butonul STOP şi inseraţi linia de cod timer1.Start().Click += new System.

IndianRed.EventArgs e) {textBox1.BackColor=Color.Yellow)textBox1. } 160 .} private void button4_MouseEnter(object sender. După adăugarea butoanelor şi a casetei text pe formular.Text+'B'.Yellow. System.textBox1. System.Yellow)textBox1.Visible=false.Text="".BackColor==Color. private void button1_Click(object sender. etichetate A. if( button1.} private void button4_MouseLeave(object sender. Culoarea butonului mare (verde/portocaliu) se schimbă atunci când mouse-ul este poziţionat pe buton. if( button3.BackColor== Color.Text=textBox1.Visible=true.Text="Starea butoanelor". Acţionarea butonului „Starea butoanelor” determină afişarea într-o casetă text a etichetelor butoanelor galbene. System. button4.BackColor=Color. else button1.YellowGreen.Orange.BackColor==Color.} private void button4_Click(object sender.IndianRed) button1. La o nouă apăsare butonul revine la culoare iniţială.button4. if( button2.EventArgs e) {button4.Yellow)textBox1.Text="Butoane apasate".EventArgs e) {textBox1.BackColor==Color. stabilim evenimentele care determină schimbarea culoriilor şi completarea casetei text.BackColor= Color.Text+'C'.Exemplul 10: Trei culori Acest exemplu afişează un grup alcătuit din 3 butoane.Text=textBox1.button4.B respectiv C având iniţial culoarea roşie.BackColor=Color.Text=textBox1.EventArgs e) { if (button1. Apăsarea unui buton determină schimbarea culorii acestuia în galben. Caseta text devine vizibilă atunci când apăsăm prima oară acest buton. System.Text+'A'.

şi

Exemplul 11: Hyperlink LinkLabel afişează un text cu posibilitatea ca anumite părţi ale textului (LinkArea) să fie desenate ca şi hyperlink-uri. Pentru a face link-ul funcţional trebuie tratat evenimentul LinkCliced. În acest exemplu, prima etichetă permite afişarea conţinutului discului C:, a doua legătură este un link către pagina www.microsoft.com/romania şi a treia accesează Notepad.

161

private void linkLabel1_LinkCliced (object sender, LinkLabelLinkClicedEventArgs e ) { linkLabel1.LinkVisited = true; System.Diagnostics.Process.Start( @"C:\" );} private void linkLabel2_LinkCliced( object sender, LinkLabelLinkClicedEventArgs e ) { linkLabel2.LinkVisited = true; System.Diagnostics.Process.Start("IExplore", "http://www.microsoft.com/romania/" );} private void linkLabel3_LinkCliced( object sender, LinkLabelLinkClicedEventArgs e ) { linkLabel3.LinkVisited = true; System.Diagnostics.Process.Start( "notepad" );}

Exemplul 12: Curba Beziers Se deschide o aplicaţie Windows Forms pe care o veţi denumi Culori. Din fereastra Properties modificaţi numele formularului redenumindu-l. Stabiliţi dimensiunea formularului şi culoarea de fond alegând una dintre cele predefinite din opţiunea BackColor. Cu ajutorul metodei Drag and drop plasaţi pe formular: un control de tip Button pe care veţi introduce textul START, un control de tip Timer iar din caseta Properties intervalul îl setaţi la 50. Executaţi dublu clic pe suprafaţa formularului şi completaţi clasa Form1 cu declararea variabilelor locale conform modelului de mai jos:

Random r = new Random(); PointF[] v = new PointF[4]; Graphics graf;

Executaţi dublu clic pe controlul timer şi completaţi funcţia timer1_Tick conform modelului de mai jos:

162

private void timer1_Tick(object sender, EventArgs e) { double u = 2 * i * Math.PI / 100; v[0].X = cx / 2 + cx / 2 * (float)Math.Cos(u); v[0].Y = 5 * cy / 8 + cy / 16 * (float)Math.Sin(u); v[1] = new PointF(cx / 2, -cy);v[2] = new PointF(cx / 2, 2 * cy); u += Math.PI / 4;v[3].X = cx / 2 + cx / 4 * (float)Math.Cos(u); v[3].Y = cy / 2 + cy / 16 * (float)Math.Sin(u); Pen p = new Pen(Color.FromArgb(r.Next(2), r.Next(200), r.Next(2))); graf.DrawBeziers(p, v); i++; }

Executaţi dublu clic pe butonul START şi completaţi funcţia button1_Click conform modelului de mai jos:
private void button1_Click(object sender, EventArgs e) {graf = this.CreateGraphics(); timer1.Start(); }

În fereastra Solution Explorer executaţi dublu clic pe Form1.Designer.cs pentru a declara variabilele globale i,cx,cy în zona de declaraţii a funcţiei InitializeComponent().

private System.Windows.Forms.Button button1; private System.Windows.Forms.Timer timer1; int i = 0, cx = 300, cy = 300;

În acest moment aplicaţia este gata. Din meniul File alegeţi opţiunea Save All şi rulaţi aplicaţia.

Metoda Dispose()

Exemplul 13:
163

Se adaugă pe un formular două butoane şi o casetă text. Apăsarea primului buton va determina afişarea textului din TextBox într-un MessageBox iar apăsarea celui de-al doilea buton va închide aplicaţia (metoda Dispose() va închide aplicaţia). După adăugarea celor două butoane şi a casetei text a fost schimbat textul afişat pe cele două butoane au fost scrise funcţiile de tratare a evenimentului Clic pentru cele două butoane:

private void button1_Click(object sender, System.EventArgs e) { MessageBox.Show(textBox1.Text); } private void button2_Click(object sender, System.EventArgs e) { Form1.ActiveForm.Dispose(); }

Metodele Clear() şi Add()
Exemplul 14: Controale pentru listare (ListBox, CheckedListBox, ComboBox, ImageList) ce pot fi legate de un DataSet, de un ArrayList sau de orice tablou (orice sursă de date ce implementează interfaţa IEnumerable). În acest exemplu elementele selectate din CheckedListBox se adaugă în ListBox. După adăugarea pe formular a CheckedListBox-ului, stabilim colecţia de itemi (Properties-ItemsCollection), butonul Selecţie şi ListBox-ul. Evenimentul Click asociat butonului Selectie goleşte mai întâi listBox-ul (listBox1.Items.Clear();) şi după aceea adaugă în ordine fiecare element selectat din

CheckedListBox. Suplimentar se afişează o etichetă cu itemii selectaţi.

164

SmallImageList (icon-urile de afişat în modurile LargeIcon. System. SmallIcon). este aceasta: class Elev { public string Nume { get.EventArgs e) { String s = "Am selectat si am adaugat itemii: ". Imagini mari. Acesta este similar grafic cu ferestrele în care se afişează fişierele dintr-un anumit director din Windows Explorer. Nota = 9 }). Details. listBox1. return elevi. set. Nota = 9 }). .Add(c).Add(new Elev() { Nume = "Nume 4". Nota = 8 }). set. pentru a defini coloanele de afişat). elevi.Add(new Elev() { Nume = "Nume 1". } } 165 Prenume = "Prenume 1". Columns (utilizat doar în modul Details. elevi.ToString(). Nota = 10 }). } public string Prenume { get. Items (elementele de afişat). printre care:    View ( selectează modul de afişare (LargeIcon. Prenume = "Prenume 4". } Exemplul 15: este un exemplu de utilizare a controlului ListView. SmallIcon. set. conţine foarte multe proprietăţi. Exemplul acesta afi ează într-un ListView o listă de elevi. } label1.CheckedItems) {listBox1. Clasa Elev con ine i o metodă statică ce returnează o listă de elevi (ne putem imagina că lista respectivă e citită din baza de date).s = s + " ".Add(new Elev() { Nume = "Nume 2".Items.Clear(). elevi. Prenume = "Prenume 2".void button1_Click(object source. } public int Nota { get. } public static List<Elev> CitesteElevi() { List<Elev> elevi = new List<Elev>(). s = s + c.Text = s. ListView este folosit pentru a afişa o colecţie de elemente în unul din cele 4 moduri (Text.Add(new Elev() { Nume = "Nume 3". Detalii).Items. LargeImageList. foreach ( object c in checkedListBox1. List)). Text+Imagini mici. Prenume = "Prenume 3". Fiind un control complex. elevi.

Left). ListViewItem lvi.ListViewSubItem lvsi.Items.Left).Add(lvi). listViewTest. lvsi = new ListViewItem.Columns. lvi.Left). } } Metoda SeteazaLista pregăte te lista pentru datele care îi vor fi servite: mai întăi îi adaugă 3 coloane.Add(lvsi).Add("Nume".Add("Prenume". listViewTest.SubItems.Sorting = SortOrder.Details.ToString().AllowColumnReorder = true.EndUpdate().Nota. foreach (Elev elev in Elev. EventArgs e) { this. HorizontalAlignment.ListViewSubItem().Add("Nota".Columns.Ascending. lvsi.Prenume.SubItems. 200. lvi. HorizontalAlignment.BeginUpdate(). listViewTest. lvsi.Nume. listViewTest. listViewTest. La Form1_Load (adică atunci când form-ul se încarcă) se vor lega datele (lista de elevi) de controlul de interfa ă.Text = elev.View = View. } this.ListViewSubItem().Columns. lvsi = new ListViewItem. } private void SeteazaLista() { listViewTest.CitesteElevi()) { lvi = new ListViewItem().listViewTest.listViewTest. 166 . 200. Codul din public Form1() { InitializeComponent(). SeteazaLista(). ListViewItem.Text = elev. } private void Form1_Load(object sender. listViewTest. 200.Text = elev.Proiectul nostru con ine Form1. HorizontalAlignment. iar apoi setează proprietă i care in de modul de afo are al acesteia.Add(lvsi).cs este acesta: i un Form unde am aşezat un control de tip ListView. lvi.

Iată exemplul (metodă executată la clic pe un buton): private void btnDeseneaza_Click(object sender. 60. } În urma rulării aplicaţiei veţi obţine: 167 .Metoda Draw() Exemplul 16: Aplicaţia este un exemplu de utilizare a controlului ImageList.Images. Acesta este un control care conţine o listă de imagini.Draw(graphic.Dispose(). i). for (int i=0. EventArgs e) { Graphics graphic = this.i++) { imageList1. i < imageList1. i * 120. care poate fi setată la design (proprietatea Collection): Controlul ImageList dispune de o metodă care permite desenarea imaginilor pe care le conţine. } graphic.CreateGraphics().Count.

Windows. an) în mod grafic. După adăugarea celor 3 controale pe formular.ToShortDateString(). TodayDate ce reprezintă data minimă/maximă selectabilă şi data curentă (care apare afişată diferenţiat sau nu în funcţie de valorile proprietăţilor ShowToday.End. În rutinele de tratare a acestor evenimente. luna.} } 168 .ToShortDateString() + " : End = "+ e.Evenimentul DateSelected Exemplul 17: MonthCalendar MonthCalendar afişează un calendar prin care se poate selecta o dată (zi. MaxSelectionCount-30.label1.ToShortDateString ()).Add(e. stabilim proprietăţile pentru monthCalendar1 (ShowWeekNumber-True. programatorul are acces la un obiect de tipul DateRangeEventArgs care conţine proprietăţile Start şi End (reprezentând intervalul de timp selectat).Start. sunt afişate săptămânile şi ziua curentă. Dacă se selectează o dată atunci aceasta va fi adăugată ca item într-un ComboBox (orice dată poate apărea cel mult o dată în listă).ShowTodayCircle.ToShortDateString().) şi precizăm ce se execută atunci când selectăm un interval de timp: private void monthCalendar1_DateSelected(object sender. System.End. if(!(comboBox1. if (e. Proprietăţile mai importante sunt: MinDate. etc. Formularul din aplicaţie conţine un calendar pentru care putem selecta un interval de maximum 30 de zile.DateRangeEventArgs e) { this.Forms.Text = "Interval selectat: Start = " +e.Items.Start.ToShortDateString()==e. Intervalul selectat se afişează prin intermediul unei etichete. Există 2 evenimente pe care controlul le expune: DateSelected şi DateChanged.End. MaxDate.Contains(x)))comboBox1.Items.ToShortDateString()) {String x=e.Start.

this.NET IDE).Cancel) { this.Font. Evenimentul cel mai util al acestui control este ButtonClic (care are ca parametru un obiect de tip ToolBarButtonClicEventArgs.Forms. fd.ShowDialog() == System. if(cd.DialogResult. iar schimbarea culorii Mutarea toolbar-ul este dirijată de evenimentele produse atunci când apăsăm butonul de mouse şi/sau ne deplasăm pe suprafaţa ferestrei.Apply += new EventHandler(ApplyFont).Evenimentele MouseDown.DialogResult.Windows. direct din Visual Studio.richTextBox1.DarkBlue.Windows. fd.Forms. Exemplul 18: Modificare proprietăţi În aplicaţia următoare cele 3 butoane fontului se realizează cu ajutorul ColorDialog().Color = Color.richTextBox1. cd. Schimbarea unui control FontDialog().Color = Color. } ColorDialog cd = new ColorDialog().richTextBox1. FontDialog fd = new FontDialog(). if(fd.ShowColor = true. MouseMove Grupuri de controale Toolbar (ToolStrip) afişează o bară de butoane în partea de sus a unui formular.ForeColor = cd.ShowDialog() != System.Color.ForeColor=fd.IndianRed.OK) this. fd.Color. Toolbar-ul se poate muta fără a depăşi spaţiul ferestrei. cd. 169 .ShowApply = true. ale toolbar-ului permit modificarea proprietăţilor utilizează textului introdus în casetă. Se pot introduce vizual butoane (printr-un designer. MouseUp.Font= fd.AllowFullOpen = true. prin care programatorul are acces la butonul care a fost apăsat). la care se pot seta atât textul afişat sau imaginea. fd.

MouseEventArgs e) { am_apasat = false.Top || toolBar1.Fixed3D.Top.Capture = true.Fixed3D.Dock = DockStyle. toolBar1. }}}}  Metoda ShowDialog() Exemplul 18: Fişiere 170 . toolBar1.Top = e.Dock == DockStyle. toolBar1.None.None) {toolBar1.toolBar1.Top>this.forma_deplasata.toolBar1. toolBar1.Location = new Point(10. toolBar1.Y < (e.Left.Left) { // daca depaseste atunci duc in stanga sus if (forma_deplasata.// Disconect toolbar toolBar1.Size. } } else if (toolBar1. 45).Left < 5 || toolBar1. toolBar1.X + toolBar1.Size = new Size(200.Y.} private void toolBar1_MouseMove(object sender.Dock = DockStyle.toolBar1.Capture = false.X-20) || forma_deplasata.private void toolBar1_MouseDown(object sender. if (toolBar1. e.Left . 10).Height-20) { am_apasat = false.BorderStyle = BorderStyle.X.} private void toolBar1_MouseUp(object sender.Top < 5 || toolBar1. forma_deplasata = new Point(e.20) { am_apasat = false.Top .Y).toolBar1.Dock == DockStyle. MouseEventArgs e) { if (am_apasat) { if(toolBar1.Y-20)) { am_apasat = false.forma_deplasata.} else if (toolBar1.Y + toolBar1.BorderStyle = BorderStyle.FixedSingle.Width .Dock == DockStyle.Dock = DockStyle.Left > this.Size.Left = e. MouseEventArgs e) { // am apasat butonul de mouse pe toolbar am_apasat = true.X < (e.BorderStyle = BorderStyle.X.

try{strm = new FileStream (of.Text+" "+str. richTextBox1.Process.Start( "notepad" ).FileName. afişarea unor informaţii teoretice precum şi Help dinamic.txt)|*.Diagnostics.aspx"). MessageBoxButtons.Process. ştergerea conţinutului casetei.Cancel)return. File Open selectează şi afişează în caseta text conţinutul unui fişier text. FileAccess. if (of.Visible=true. Au fost definite chei de acces rapid pentru accesarea componentelor meniului. "http://msdn2.Text="".txt". afişarea continutului acestuia într-o casetă text.Filter = "Text Files (*. File New permite scrierea unui fişier notepad nou System. schimbarea fontului şi culorii de afişare. MessageBoxIcon. File Exit închide aplicaţia Window  Font şi Window Color permit stabilirea fontului/culorii textului afişat.Start("IExplore".microsoft. FileStream strm.ReadLine (). "File Error".} File Close şterge conţinutul casetei text.Exemplul permite. scrierea unui fişier Notpad. Help About PV afişează în caseta text informaţii despre implementarea unui meniu. while (rdr.Show ("Error opening file". of.Exclamation). richTextBox1.Read).Text=richTextBox1. }} catch (Exception) {MessageBox.ShowDialog() == DialogResult. of.com/en-us/default. prin intermediul unui meniu. StreamReader rdr = new StreamReader (strm). 171 . richTextBox1.Peek() >= 0) {string str = rdr. OpenFileDialog of = new OpenFileDialog().Diagnostics.OK. FileMode.Open. Help DinamicHelp accesează System.Title = "Fisiere Text".

30).4.II. Un obiect de tip Point este reprezentat prin coordonatele unui punct într-un spaţiul bidimensional Exemplu: Point myPoint = new Point(1. Structura Color conţine date. Fiind un tip valoare (struct) şi nu o clasă. blue). Putem construi un obiect de tip Point pentru a redimensiona un alt obiect. constructori. Point este utilizat frecvent nu numai pentru desene. însă nu permite instanţiere. Console. Color myColor = Color. Clasa Graphics este o clasă sigilată reprezentând o arie rectangulară reprezentări grafice.BackColor = myColor. tipuri şi metode utile în lucrul cu culori. aceasta conţine date şi metode. Size mySize = new Size(15. De exemplu. Y: " + myPoint.Drawing conţine tipuri care permit realizarea unor desene 2D şi au rol deosebit în proiectarea interfeţelor grafice. button1.Brown. pentru a modifica poziţia unui buton în fereastră putem asigna un obiect de tip Point proprietăţii Location indicând astfel poziţia colţului din stânga-sus al butonului Exemplu: button. moştenire. Substructura FromArgb a structurii Color returnează o culoare pe baza celor trei componente ale oricărei culori (red. 100). green. o linie frântă se poate realiza astfel: care permite 172 .X + ".WriteLine("X: " + myPoint.Location = new Point(100. Point myPoint = new Point(mySize). ci şi pentru a identifica în program un punct dintr-un anumit spaţiu.5.Y). De exemplu. Obiecte grafice Spaţiul System. destructor. 2).

Graphics g = this. 120). 0).} catch{MessageBox.jpg"). x.Sleep(200).Zero). PaintEventArgs e) {e.Next(256))). i. Exemplul 19: Pictogramă În exemplul următor se construieşte o pictogramă pe baza unei imagini. Graphics g = this.Show("Nu exista fisierul"). i).FromFile("C:\\Imagini\\catel.Next(256).Next(1000). 0). Pen pen = new Pen(Color.null. points[0] = new Point(0. IntPtr.points[3] = new Point(20.Beep(300 + x. Random x = new Random().g.FromArgb(x. 10. thumbnail=img. private void Thumbnails_Load(object sender.CreateGraphics(). x. int latime=100. Image thumbnail. 10). Exemplul 19: Desen Aplicaţia este un exerciţiu care desenează cercuri de raze şi culori aleatoare şi emite sunete cu frecvenţă aleatoare. inaltime=100. x.Next(256). Pen p = new Pen(Color.DrawLines(pen.} } private void Thumbnails_Paint(object sender. Console.DrawImage(thumbnail.Graphics.Yellow. Thread. 2). points[2] = new Point(20. inaltime.CreateGraphics(). g.Point[] points = new Point[4].Next(100). EventArgs e) { try{Image img = Image. 120). x.GetThumbnailImage(latime.Next(30).points[1] = new Point(0.} 173 .Next(100). int i = 1 + x.DrawEllipse(p. 150). points).

Forms. Textchanged. pentru a preveni posibilele erori.II. dacă utilizatorul introduce o valoare reală (float) când aplicaţia aşteaptă un întreg (int).) private void textBox1_KeyUp(object sender. Acest aspect este important.(2) Validarea la nivel de utilizator În unele situaţii (de exemplu atunci când valorile introduse trebuie să se afle într-o anumită relaţie între ele). II. validarea se face la sfârşitul introducerii tuturor datelor la nivelul unui buton final sau la închiderea ferestrei de date. 174 . MouseUp etc. Astfel.Windows.5. Validarea informaţiilor de la utilizator Înainte ca informaţiile de la utilizator să fie preluate şi transmise către alte clase. System. fiind foarte greu de identificat cauza primară a problemei.5. este posibil ca aceasta să se comporte neprevăzut abia câteva secunde mai târziu.(1) Validarea la nivel de câmp Datele pot fi validate pe măsură ce sunt introduse.5.Alt==true) MessageBox.KeyChar)==true) MessageBox. asociind o prelucrare unuia dintre handlerele asociate evenimentelor la nivel de control (Leave. este necesar să fie validate.IsDigit(e. } II. // sau if(Char.Show ("Tasta Alt e apasata").5.Show("Ati apasat o cifra").KeeyEventArgs e) {if(e. şi după multe apeluri de metode.5.5.

Control a in this.Show("BUNA ZIUA!"). să deschidă o altă fereastră cu un mesaj: “BUNA ZIUA!” Pe fereastra care apare la iniţializarea proiectului nostru. în care vom folosi câteva controale şi vom explica ceea ce se întâmplă din punct de vedere al programării orientate obiect.TextBox & a.return.Forms. vom plasa un buton pe care scriem: “APASATI”.Text=="") { a.Controls) { if( a is System.private void btnValidate_Click(object sender.5. II. dacă-l apăsăm.Windows. pe care.5.Focus(). Pentru a compila şi executa apăsăm F5.SetError(txtName.Forms.} } } II.6. Dăm dublu clic pe respectivul buton şi scriem codul în funcţia generată de această acţiune: MessageBox.EventArgs e) { foreach(System. Obţinem: 175 . MessageBox Ne propunem ca în cele ce urmează să realizăm o aplicaţie simplă.5. myErrorProvider." Numele nu are spatii in stanga").(3) ErrorProvider O manieră simplă de a semnala erori de validare este aceea de a seta un mesaj de eroare pentru fiecare control .Windows. Ne propunem să construim o fereastră cu un buton. System.

Windows. fereastra cu acest mesaj se închide. 176 . "Salut"). Să considerăm acum apelul funcţiei Show cu doi parametri: al doilea parametru se va referi la textul care apare pe bara de titlu în fereastră de mesaje: MessageBox. Apelul acestei funcţii se va face în funcţie de parametri.Show("BUNA ZIUA!". derivată din clasa Object Show este o metodă statică din clasa MessageBox În momentul în care se apasă butonul OK. aducându-ne aminte de noţiunile de programare orientată obiect studiate:   MessageBox este o clasă din spaţiul de nume System.Forms.Să analizăm puţin codul nostru. metoda Show cedând controlul. Metoda Show are mai multe forme în clasa MessageBox. fiind supradefinită.

Asterisk). 177 . alături de textul “BUNA ZIUA”. "Salut".YesNo).Show("BUNA ZIUA!". "Salut".YesNo. Să mai încercăm o altă formă supradefinită a metodei Show.Show("BUNA ZIUA!". MessageBox.Să considerăm în continuare apelul funcţiei Show cu trei parametri: al treilea parametru se va referi la butoanele care pot să apară în fereastra de mesaje (sunt şase variante): MessageBox. MessageBoxButtons. MessageBoxButtons. folosind patru parametri: al patrulea se va referi la icoana care să apară. Avem la dispoziţie 9 icoane. MessageBoxIcon.

dorim să ne realizăm o interfaţă proprie.7.5. Presupunem că dorim ca fereastra să aibă forma de oval. 178 . Interfaţă definită de către utilizator Sunt multe aplicaţii în care. de exemplu. aplicaţia Paint. ca formă.II. în locul celei dreptunghiulare propusă de Visual C#. exemplul de mai jos ne va da o idee asupra a ce trebuie să facem în acest caz. Pentru aceasta vom folosi. În primul rând trebuie să ne desenăm propria fereastră de viitoare aplicaţii. Dacă da. poate. Desenăm o figură geometrică care va constitui viitoarea noastră fereastră.

Colorăm ovalul cu o culoare dorită. reţinând codul ei RGB 179 . iar pentru fundal alegem orice culoare.

Din PictureBox Task aleg imaginea care să apară: oval. iar ca nume InterfataUtilizator Aduc controlul PictureBox.în cazul nostru: Red: 255 Greeen: 255 Blue: 0 Salvăm desenul cu extensia gif: oval. Alegem: File | New Project | Windows Forms Application.gif Să trecem acum la Visual C#.jpg iar la Size Mode aleg StretchImage astfel încât imaginea să fie toată în PictureBox Deformez PictureBox-ul astfel încât ovalul desenat să ocupe o suprafaţă care să corespundă esteticii programatorului 180 .

iar la proprietăţile corespunzătoare voi selecta:   BackColor 255.255. iar fundalul este transparent. deocamdată. Această fereastră o putem deplasa. o fereastră în care există ovalul desenat de noi. 181 .Selectez Form1.(aceleaşi valori ca şi la culoarea fundalului) Dacă vom compila observăm că obţinem. deocamdată doar folosind proprietatea barei de titlul atunci când ţinem cursorul mouse-ului apăsat pe ea.0 – în acest moment fundalul ferestrei coincide ca şi culoare cu fundalul desenului nostru TransparencyKey 255.0 .255.

Aducem în Fereastra noastră un buton pe care-l vom folosi pentru închiderea ferestrei rezultat 182 .Închidem fereastra rezultat şi ne continuăm proiectul.

Dăm dublu clic pe evenimentul MouseDown şi scriem în Fereastra Form1. int Param1.Button == MouseButtons. } Mai includem în sursa noastră şi: 183 . 0). Dăm clic pe PictureBox.dll")] public static extern int SendMessage(IntPtr Handle.cs codul corespunzător butonului stânga al mouse-ului.dll este o bibliotecă ce conţine rutine pentru interfaţa utilizator (ferestre.Close(). int Msg.dll în codul nostru: User32. 0x2. [DllImport("User32.dll")] public static extern bool ReleaseCapture(). meniuri.Left) { ReleaseCapture(). ne ducem la Fereastra Properties şi selectăm evenimentele legate de acest control. mesaje etc. 0xA1. cod ce se referă la posibilitatea de a putea prinde şi deplasa interfaţa noastră: if (e. Includem biblioteca User32. SendMessage(Handle.) [DllImport("User32.Scriem codul corespunzător dând dublu clic pe buton: this. int Param2).

Data.Runtime. selectăm Form1.Runtime. 0). System. } } } } Revenim în fereastra Form1. int Param2). În final codul arată: using using using using using using using using System. 0x2. SendMessage(Handle. EventArgs e) { this. [DllImport("User32. System. } private void button1_Click(object sender.InteropServices.Collections.using System.dll")] public static extern int SendMessage(IntPtr Handle. } private void pictureBox1_MouseDown(object sender.Drawing.Generic. System.InteropServices.dll")] public static extern bool ReleaseCapture().Button == MouseButtons.ComponentModel.cs[Designer]. System. int Msg. MouseEventArgs e) { if (e.Text. namespace Interfata3 { public partial class Form1 : Form { [DllImport("User32. System. System.Left) { ReleaseCapture().Windows.Close(). int Param1. iar la Properties alegem: FormBorderStyle – None 184 . 0xA1. public Form1() { InitializeComponent().Forms. System.

Apăsăm F5 şi surpriză (plăcută  ): obţinem ceea ce ne-am propus: 185 .

Text).II. navigatorul nostru funcţionează! 186 .Navigate(textBox1. Surpriză plăcută. În Visual C# alegem: File | New Project | Windows Forms Application. În această fereastră aducem:  TextBox la care. la TextBox Tasks bifăm MultiLine   Button la care-i schimbăm Text-ul în GO WebBrowser pe care îl aliniem după laturile din stânga.8. Browser creat de către utilizator O aplicaţie interesantă constă în a ne crea propriul browser. în Fereastra Properties.5. Rulăm programul şi în TextBox vom scrie o adresă web. dreapta şi jos a ferestrei. iar ca nume BrowserUtilizator. Dăm dublu clic pe butonul GO şi scriem codul necesar navigării: webBrowser1. cuvânt care va apare pe bara de titlu. la Text scriem B R O W S E R. În Form1.

Necazurile încep în momentul în care încercăm să maximizăm fereastra browser-ului pentru a putea vizualiza mai bine informaţiile afişate. Din păcate în acel moment obţinem:

187

Observăm că fereastra WebBrowser-ului nu s-a maximizat odată cu cea a ferestrei aplicaţiei. Rezultă că această încercare de a realiza un browser propriu nu este corectă. Vom încerca altă metodă. De la grupul de controale Container aleg SplitContainer. De la opţiunea Split Container Task aleg Horizontal splitter orientation

188

Deformez cele două panouri ale containerului astfel încânt panoul de mai sus să fie mai mic, iar Panoul 2 să ocupe o suprafaţă mai mare din fereastra noastră. În Panoul 1 vom plasa TextBox-ul şi Button-ul, iar în Panoul 2 WebBrowser-ul. Pentru WebBrowser aleg proprietatea Doc in parent container, moment în care WebBrowser-ul se va lipi (va adera) de marginile marginile Panoului 2 Dăm dublu clic pe butonul GO şi scriem acelaşi cod ca mai înainte. Rulăm programul şi observăm că dacă maximizăm fereastra WebBrowser-ul rămâne lipit de marginile ferestrei. Singurul lucru care nu ne mulţumeşte este faptul că la maximizarea ferestrei TextBox-ul şi Button-ul rămân pe loc şi nu aderă la marginile ferestrei. Să corectăm acest lucru. Selectăm TextBox-ul. după care din fereastra Properties dăm clic în căsuţa corespunzătoare proprietăţii Anchor. Suntem asistaţi grafic pentru a stabili partea în care dorim ca TextBox-ul să fie lipit de margini.

189

Alegem Stânga, Dreapta şi Sus dând clic pe segmentele corespunzătoare. La fel procedăm pentru butonul GO, unde alegem Sus şi Dreapta Din acest moment cele două controale aflate în Panoul 1 se vor deplasa odată cu marginile ferestrei. Browserul nostru poate fi îmbunătăţit, în sensul adăugării de noi butoane care să ofere utilizatorului opţiuni suplimentare: pentru navigarea înapoi în lista de adrese pentru navigarea înainte în lista de adrese pentru pagina de start

Cele patru butoane le putem alinia şi aduce la aceeaşi dimensiune folosind opţiunile de pe bara de instrumente:

Selectarea tuturor butoanelor se poate face fie cu clic şi Ctrl pe fiecare, fie înconjurând cu mouse-ul respectivele butoane (în acest timp butonul stâng al mouse-ului este apăsat). Pe butoane fiecare poate să pună, după gustul său, imagini în loc de aceste simboluri.
190

5. //pagina goala sau webBrowser1.Navigate("www. SaveFileDialog. Right Top. Ceas Utilizatorul nu are drept de control asupra tuturor controalelor. împreună cu ferestra aplicaţiei.Vom scrie în continuare codul corespunzător fiecărui buton. Right Top. FontDialog. ColorDialog. acesta nu se afişează pe formular.com"). ContextMenu). Observăm că aducând din Toolbox controlul Timer. Left.GoForward(). o putem realiza doar folosind proprietatea Anchor pentru toate elementele din fereastră. Dintre acestea vom studia în cele ce urmează controlul Timer asupra căruia are drept de interacţiune doar cel care dezvoltă aplicaţia.9. Right II.//sau orice alta //adresa web O altă metodă pentru deformarea proporţională a WebBrowser-ului. 191 . el apărând într-o zonă gri a suprafeţei de lucru (Designer). control textBox button webBrowser Anchor Top. Left. Bottom. webBrowser1.GoBack(). dând dublu clic pe respectivul control: webBrowser1. Există controale „de control” al executării (Timer) sau de dialog (OpenFileDialog.GoHome(). webBrowser1.google.

în cazul de faţă numărătoarea din secundă în secundă Aducem în formular un control Label cu următoarele proprietăţi: Control label1 Proprietate (Name) AutoSize BorderStyle FontSize Location Valoare labelCeas False Fixed3D 16.112 192 .Vom stabili următoarele proprietăţi legate de Timer: Proprietate (Name) Valoare aplCeas Explicaţie Enabled Interval True 1.25. Se stabileste. Bold 82.000 Activarea controlului de timp Numărul de milisecunde dintre apelurile la metoda de tratare a evenimentului.

Text=OraCurenta.Text Size TextAlign 129.Now.42 MiddleCenter Dăm clic pe icoana de la timer care are numele aplCeas. EventArgs e) { DateTime OraCurenta = DateTime. iar la Events. lblCeas. la Tick selectăm aplCeas_Tick Dăm dublu clic pe aplCeas_Tick şi inserăm codul: private void lblCeas_Tick(object sender. } Compilăm şi obţinem într-o fereastră vizualizarea orei sistemului 193 .ToLongTimeString().

1. Accesarea şi prelucrarea datelor prin intermediul SQL Server Crearea unei baze de date. executaţi clic pe butonul din dreapta al mouse-ului după selectarea folderului Databases. de unde alegeţi opţiunea New Database. 194 . În momentul deschiderii aplicaţiei fereastra acestei aplicaţii va conţine fereastra Object Explorer. fereastra Sumarry şi fereastra Properties.II.6. Pentru a crea o nouă bază de date din fereastra Object Explorer ce se află în stânga ferestrei principale. Pentru a realiza acest lucru trebuie să deschideţi aplicaţia Microsoft SQL Server Management Studio Express.6. Conectare şi deconectare. II. Înainte de a crea orice obiect al unei baze de date trebuie să creăm baza de date. şi să acceptaţi conectarea la server-ul local..

195 . Creaţi un tabel alegând în acelaşi mod ca şi cel prezentat mai sus opţiunea New Table. din acest motiv este bine să utilizaţi unul dintre tipurile de date ce vă apar în lista derulantă Stabiliţi cheia primară a tabelei prin selectarea rândului unde doriţi să stabiliţi cheia primară şi apoi prin executarea unui clic pe butonul din dreapta al mouse-ului şi alegerea opţiunii Set Primary Key. Definiţi coloanele tabelului prin stabilirea componentelor:  numele coloanei – acesta trebuie să fie unic în cadrul tabelei  tipul de date – tipul de date trebuie să fie un tip de date valid. din folder-ul Table.Denumiţi această bază de date (în exemplul de mai jos noi i-am spus CLASA).

Pentru a salva tabela creată până acum executaţi clic dreapta pe numele tabelei. II.6. alegeţi opţiunea Save Table şi stabiliţi cu această ocazie şi numele nou al tabelei. Popularea bazei de date Pentru a introduce date în tabelă chiar de la crearea ei executaţi clic dreapta pe butonul mouse-ului după selectarea fişierului şi alegeţi opţiunea Open Table.2. 196 .

6. Dacă operaţiile efectuate pe server sunt mai multe (calcule complexe de ex. Acest lucru poate fi realizat cu ajutorul procedurilor stocate sau cu ajutorul opţiunii SQLCMD. De asemenea.) atunci e mai simplu să apelaţi la procesarea în Stored Procedures şi să returnaţi doar o listă mică de rezultate. care poate fi apelata de aplicaţii diferite. procedurile stocate pot avea parametri. ceea ce creste eficienţa utilizării lor. Pentru a realiza acest lucru va trebui să alegeţi opţiunea New Stored Procedure executând clic pe butonul din dreapta al mouse-ului pe folderul Stored Procedures din folderul Programmability al bazei de date pe care o prelucraţi.3. Sql Server compilează procedurile stocate. Asta mai ales când procesarea necesită prelucrarea unui volum mare de date. Introducere în limbajul SQL II. O procedură stocată este o secvenţă de instrucţiuni SQL. II.Deconectarea de la baza de date se realizează prin alegerea opţiunii Disconect Object Explorer din meniul File al aplicaţie. iar în cazul în care aplicaţia este deschisă şi dorim reconectarea la baza de date alegem din meniul File opţiunea Connect Object Explorer. Va trebui să apelaţi la scrierea lor în cod.6. 197 .(1) Introducere ANSI SQL Anumite instrucţiuni cum ar fi Alter sau Create nu sunt accesibile din meniu.3. salvată in baza de date. gata procesate.

 FROM specifică lista tabelelor sau vizualizărilor de unde selectăm date.3. SELECT [ID] .6.[NUME] FROM [elev].[dbo]. Pentru a selecta toate coloanele se poate folosi simbolul asterisc *.[T1] Exemplul 1: am cerut să vizualizez înregistrarile din coloanele ID şi NUME ale tabelului Elev din baza de date CLASA.(2) Select Forma instrucţiunii SELECT conţine două clauze:  SELECT[DISTINCT] specifică lista coloanelor ce urmează să fie returnate în setul de rezultate. Cuvântul cheie DISTINCT adăugat după cuvântul cheie SELECT elimină rândurile duplicat din rezultatele înregistrării.II. Exemplul 2: procesarea mai multor comenzi cu SQLCMD 198 .

va incrementa această valoare cu o unitate. înregistrare care va primi pe coloana NUME valoarea POPESCU. Ea poate fi folosită în două variante:  pentru a crea un singur rând la fiecare rulare.[dbo]. Observaţie: . INSERT INTO [elev]. obţinând astfel cheia primară a unei noi înregistrări.6.lista de coloane este opţională.> .[T1] ([ID] . Pentru a vizualiza modificarea folosiţi instrucţiunea SELECT.cuvântul cheie NULL poate fi folosit în lista de valori pentru specificarea unei valori nule pentru o coloană Exemplul2: de utilizare a instrucţiunii INSERT cu includerea listei de coloane. în acest caz valorile pentru rândul de date respectiv sunt specificate chiar în instrucţiune INSERT INTO nume_tabel [(lista_de_coloane)] VALUES (lista_de_valori).II.<NUME. dar dacă este inclusă trebuie să fie încadrată între paranteze . numeric.[NUME]) VALUES (<ID. 199 . nvarchar(50).3.(3) Insert Instrucţiunea Insert este folosită pentru inserarea noilor rânduri de date în tabele.>)  pentru a insera rânduri multiple într-un tabel se foloseşte o instrucţiune SELECT internă Exemplul 3: în acest exemplu instrucţiunea SELECT va găsi valoarea maximă de pe coloana ID. Pentru a vizualiza modificarea folosiţi instrucţiunea SELECT.

NUME) SELECT MAX(ID)+1. Cu ajutorul instrucţiunii Update vom modifica acest ID. dar dacă este inclusă trebuie să fie încadrată între paranteze .> WHERE <Search Conditions.3..[dbo].dbo.cuvântul cheie NULL poate fi folosit în instrucţiunea SELECT pentru specificarea unei valori nule pentru o coloană II.[CLASA] SET [ID] = <ID.CLASA Observaţie: .(4) Update Instrucţiunea Update este folosită pentru actualizarea datelor din coloanele unui tabel Sintaxa ei este următoarea: UPDATE [elev].INSERT INTO elev.dbo.[NUME] = <NUME.> Exemplul 4: presupunem că am greşit ID-ul elevului POPESCU în loc de 7 ar fi trebuit să introducem 21.> . numeric.'POPESCU' FROM elev.CLASA (ID . nvarchar(50).6.lista de coloane este opţională. Pentru a vizualiza modificarea folosiţi instrucţiunea SELECT. 200 .

dbo.[dbo].> Exemplul 5: modificaţi numele elevului cu ID-ul 2 din ADAM în POPESCU. împreună cu o expresie care specifică noua valoare pentru fiecare coloană .[CLASA] WHERE <Search Conditions. inclusiv toate valorile datelor din rândurile afectate.Observaţii: . dar ATENŢIE dacă veţi renunţa la ea se vor şterge toate înregistrările existente .3. modificarea tipului de date al unui rând.(5) DELETE Instrucţiunea DELETE şterge unul sau mai multe rânduri dintr-un tabel.CLASA SET NUME = 'POPESCU' WHERE ID=2 Folosiţi acum instrucţiunea DELETE astfel: DELETE FROM elev. sau modificarea cheii primare. Dacă o omitem se vor actualiza toate rândurile tabelului. UPDATE elev. II. Va fi ştearsă orice înregistrare pentru care condiţia indicată este adevărată.3. DELETE FROM [elev].atunci când includeţi clauza WHERE ea specifică rândurile care urmează a fi şterse.CLASA WHERE NUME='POPESCU' Observaţii: .6.clauza SET conţine o listă cu una sau mai multe coloane.(6) Comenzi de manipulare tabele  MODIFY – ne permite modificarea numelui unei coloane.. În instrucţiunea DELETE nu sunt referite niciodată coloane.clauza WHERE conţine o expresie care limitează rândurile ce vor fi actualizate.6. deoarece instrucţiunea şterge rânduri întregi de date. 201 . II.clauza WHERE este opţională. pentru a avea două înregistrări cu acelaşi nume.dbo.

putând nominaliza o serie de parametri facultativi (sunt acceptate sau nu valorile nule. Exemplul 7: 202 . alter table nume_tabel add <definitie coloana> unde <definitie coloana>=nume_tabel tip_de_date  CREATE CREATE [TEMPORARY] TABLE [IF NOT EXISTS] nume_tabela Nume_camp tip_camp [NOT NULL | NULL] [DEFAULT default_value] AUTO_INCREMENT] [PRIMARY KEY] [reference_definition] Pentru fiecare câmp se stabileşte numele şi tipul acestuia. verificare. Cu ajutorul ei se pot specifica toate restricţiile necesare(cheie primară. unicitate. ALTER TABLE <nume tabela> ADD|DROP|MODIFY (specificaţii privind coloana modificata sau nou creata). aproape tot ceea ce aţi specificat în instrucţiunea CREATE TABLE poate fi modificat folosind instrucţiunea ALTER TABLE. Exemplul 6: dorim să adăugăm o coloană la un tabel creat anterior. etc). ALTER După ce aţi creat un tabel. cheie externă. câmpul sa fie autoincrementat sau sa fie creat drept cheie primară). setarea valorii implicite.

6.. II. Pentru a popula aceasta tabelă trebuie să o deschideţi cu Open.(7) Manipularea datelor  FUNCŢIA COUNT – returnează numărul de câmpuri dintr-o tabelă care corespund interogării.Pentru a executa aceasta comanda faceti clic pe butonul Pentru a vizualiza efectul acestei comenzi folosiţi comanda Select ca in exemplul de mai jos iar apoi executaţi clic pe mouse pe butonul După cum observaţi se pot vizualiza câmpurile definite în tabela Flori. Sintaxa instrucţiunii este: SELECT COUNT (nume coloana) FROM nume tabel WHERE <Search Conditions.3. 203 .> Exemplul 8: pentru tabela Salarii am cerut câte persoane au salariu mai mare decât 1200.

SELECT SUM(column_name) FROM table_name Exemplul 9: pentru tabela Salarii cerem suma tuturor salariilor înregistrate pe coloana Salar. Funcţia SUM – returnează suma totală dintr-o coloană a cărei tip de date a fost declarat iniţial numeric.  Funcţia Min – returnează cea mai mică valoare înregistrată pe o coloană Sintaxa: SELECT MIN(column_name) FROM table_name Exemplul 11: cerem să se afişeze cel mai mare salariu din tabela Salarii.  Funcţia Max – returnează cea mai mare valoare înregistrată pe o coloană Sintaxa: SELECT MAX(column_name) FROM table_name Exemplul 10: cerem să se afişeze cel mai mare salariu din tabela Salarii. 204 .

205 . Meniul Data şi fereastra auxiliară Data Sources ne sunt foarte utile în lucrul cu surse de date externe. „La vedere” se află controale de tip DataGridView. Accesarea şi prelucrarea datelor cu ajutorul mediului vizual Mediul de dezvoltare Visual Studio dispune de instrumente puternice şi sugestive pentru utilizarea bazelor de date în aplicaţii.1. După crearea unei baze de date în SQL informaţiile înregistrate în tabela sau tabelele bazei de date pot fi utilizate într-o aplicaţie din Visual C# într-un formular sau într-o aplicaţie consolă. Vom prezenta acum modul în care se poate utiliza o bază de date într-un formular creat în Windows Forms. sau TableGridView.7. BindingNavigator etc. Pentru a realiza acest lucru după deschiderea aplicaţiei din fereastra Toolbox trageţi pe formular cu ajutorul procedeului drag-and-drop o DataGridView. Ordonarea datelor dintr-o tabelă – se poate realiza cu ajutorul instrucţiunii Order By Sintaxa: SELECT column_name(s) FROM table_name ORDER BY column_name(s) ASC|DESC Exemplul 12: am cerut să se ordoneze alfabetic datele înregistrate pe coloana Nume din tabela Salarii. Conectare şi deconectare.7. DataAdapter şi DataSet prezentate. II. în spatele unei ferestre în care lucrăm cu date preluate dintr-una sau mai multe tabele ale unei baze de date se află obiectele din categoriile Connection. conform exemplului de mai jos. Conceptual. II. Command.

alegeţi imediat după aceasta sursa de date şi baza de date urmărind exemplele de mai jos. Înainte de a finaliza prin executarea unui clic pe butonul Ok din fereastra Add Connection.Alegeţi sursa de date pentru acest proiect executând clic pe butonul AddProject Data Source din fereastra DataGridView Task. nu uitaţi să verificaţi conexiunea executând clic pe butonul Test Connection. Conexiunea la baza de date se finalizează prin alegerea obiectului pe care doriţi să îl utilizaţi în formularul creat. 206 .

După finalizarea conexiunii sursa generată o puteţi vizualiza în Form1. }}} Rulaţi aplicaţia alegând opţiunea Start Debugging din meniul Debug şi veţi obţine afişarea datelor într-un formular ca în exemplul de mai jos. Cheia primară se poate stabili din fereastra SalariiDataset executând clic pe butonul din dreapta al mouse-ului şi alegând opţiunea Set Primary Key pentru câmpul respectiv. tabela utilizată fiind SALAR_ANGAJAT. Afişarea înregistrărilor din tabelă se poate obţine şi prin alegerea opţiunii Preview din fereastra DataGridView Task şi executând clic pe butonul Preview din fereastra care se deschide Preview Data .cs.sALAR_ANGAJATTableAdapter.Fill(this. EventArgs e) { this. Pentru exemplul nostru am ales o bază de date numită SALARII. } private void Form1_Load(object sender. 207 . Exemplul 1: namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent().SALAR_ANGAJAT ).sALARIIDataSet.

După cum observaţi opţiunile prezente în acest meniu vă mai pot ajuta să ştergeţi o coloană în tabel. Toate instrucţiunile prezentate în capitolul Introducere în limbajul SQL pot fi accesate şi pe un formular. Meniul contextual asociat grilei în care vor fi vizualizate datele permite configurarea modului de lucru cu grila (sursa de date. BindingNavigator şi. în dreapta. 208 . ştergere şi adăugare în tabel. prin instanţiere. Operaţii specifice prelucrării tabelelor Atunci când într-un formular utilizăm un tabel trebuie să avem posibilitatea de a utiliza funcţiile ce operează asupra datelor incluse în el. operaţiile permise şi altele). să inseraţi o coloană din tabel să stabiliţi sau să modificaţi proprietăţile unei coloane deja definite sau să vizualizaţi codul generat.Stabiliţi cheia primară a tabelei prin selectarea rândului unde doriţi să stabiliţi cheia primară şi apoi prin executarea unui clic pe butonul din dreapta al mouse-ului şi alegerea opţiunii Set Primary Key.2.7. TableAdapter. BindingNavigator este un tip ce permite. Se observă că reprezentarea vizuală a fiecărui obiect este înzestrată cu o săgetă în partea de sus. Un clic pe această săgeată activează un meniu contextual cu lista principalelor operaţii ce se pot efectua cu obiectul respectiv. în fereastră. construirea barei de navigare care facilitează operaţii de deplasare. TableGridView. BindingSource. se creează automat obiecte specifice. II. Prin "tragerea" unor obiecte din fereastra Data Sources în fereastra noastră nouă. În partea de jos a figurii se pot observa obiectele de tip Dataset. editare.

NET ADO. Accesarea şi prelucrarea datelor cu ajutorul ADO.NET Framework ce permite conectarea la surse de date diverse. executaţi clic pe butonul Query Builder pentru a vizualiza efectul. manipularea şi actualizarea datelor.Prezentăm un exemplu pentru inserarea unor noi date în tabelul Salar_Angajat:  alegaţi opţiunea Add Query din SALAR_ANGATTableAdapter Tasks  introduceţi instrucţiunea INSERT în forma dorită. si clic pe butonul Execute Query pentru a o lansa în execuţie  confirmarea introducerii noii înregistrări o veţi obţine imediat  pentru a vizualiza efectul acestei instrucţiuni puteţi lansa în execuţie aplicaţia În acelaşi mod se pot utiliza celelalte instrucţiuni şi funcţii ale limbajului SQL.8. extragerea.NET (ActiveX Data Objects) reprezintă o parte componentă a nucleului . 209 . II.

Programabilitate. ADO. ceea ce permite accesarea datelor din diferite surse de diferite tipuri şi prelucrarea lor ca entităţi. sursa de date este o bază de date. o foaie Excel.NET poate interacţiona uşor cu orice componentă care suportă XML. 210 . Ele au fost proiectate pentru accesarea şi manipularea datelor. Nu mai este necesară conversia explicită a datelor la transferul între aplicaţii.NET Componentele principale ale ADO.NET permite şi lucrul în stil conectat dar şi lucrul în stil deconectat.1. dar ar putea de asemenea să fie un fişier text. furnizând o reprezentare comună a datelor. ADO.  Durabilitate. Conexiunile deschise necesită alocarea de resurse sistem.  Performanţă.  Accesibilitate. In aplicaţiile tradiţionale cu baze de date. ADO. Reducerea numărului de conexiuni deschise resurselor. un fişier Access sau un fişier XML. Acest lucru permite reducerea numărului de conexiuni deschise simultan la sursele de date.NET simplifică programarea pentru diferite task-uri cum ar fi comenzile SQL. Atunci când menţinem mai multe conexiuni deschise server-ul de baze de date va răspunde mai lent la comenzile clienţilor întrucât cele mai multe baze de date permit un număr foarte mic de conexiuni concurente. ceea ce duce la o creştere a productivităţii şi la o scădere a numărului de erori. ADO. clienţii stabilesc o conexiune cu baza de date şi menţin această conexiune deschisă până la încheierea executării aplicaţiei. Utilizarea arhitecturii deconectate permite accesul simultan la acelaşi set de date. simultan determină utilizarea optimă a II. fapt care duce la creşte performanţelor acestora.NET: Interoperabilitate.NET oferă instrumentele de utilizare şi reprezentare XML pentru transferul datelor între aplicaţii şi surse de date.8. Aceste caracteristici sunt determinate în stabilirea beneficiilor furnizate de ADO. fără să fie necesar să convertim explicit datele în format XML sau invers.De obicei. ADO. Arhitectura ADO. aplicaţiile conectându-se la server-ul de baze de date numai pentru extragerea şi actualizarea datelor.NET permite dezvoltarea arhitecturii unei aplicaţii datorită modului de transfer a datelor între nivelele arhitecturale.NET sunt DataSet şi Data Provider.

Command. numele şi parola contului de acces.3. pornirea unei tranzacţii etc. Fiecare furnizor de date cuprinde componentele Connection. metode pentru deschiderea/închiderea conexiunii. precizându-i ca parametru un şir de caractere conţinând date despre conexiune. DataReader şi DataAdapter.NET Framework include SQL Server. Pentru deschiderea unei conexiuni prin program se poate instanţia un obiect de tip conexiune.8. Sau implicit : 211 .Initial Catalog=SALARII. OleDb etc. Oracle Data Provider pentru bazele de date Oracle şi OLE DB Data Provider pentru accesarea bazelor de date ce utilizează tehnologia OLE DB pentru expunerea datelor (de exemplu Access. Toate exemplele pe care le vom prezenta în continuare vor avea la bază o tabelă cu următoarea structură: Exemplul 2: conexiunea se face introducând explicit numele serverului ca în exemplul de mai jos SqlConnection con = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS.2.8. Conectare Înainte de orice operaţie cu o sursă de date externă. OleDbConnection etc. trebuie realizată o conexiune (legătură) cu acea sursă.Data. Furnizori de date (Data Providers) Din cauza existenţei mai multor tipuri de surse de date este necesar ca pentru fiecare tip de protocol de comunicare să se folosească o bibliotecă specializată de clase.) conţin date referitoare la sursa de date (locaţia.IntegratedSecurity=SSPI"). II.NET Data Provider pentru interacţiune cu Microsoft SQL Server.) ale spaţiului System.II. . Furnizorul de date permite unei aplicaţii să se conecteze la sursa de date. Aceste clase se găsesc în subspaţii (SqlClient. ele implementează interfaţa IdbConnection.). Clasele din categoria Connection (SQLConnection.0). execută comenzi şi salvează rezultate. În plus. etc. Excel sau SQL Server versiune mai veche decât 7.

Baza de date trebuie să se găsească pe serverul Catalog dat în Data Source Integrated Logarea se face cu user-ul configurat pentru Windows.3. Fetching.\\SQLEXPRESS. Parametru Exemplul 3: SqlConnection con = new SqlConnection(". Closed. şi nu se specifică pentru conectare la SQL Server. Acest furnizor Provider trebuie precizat doar dacă se foloseşte OLE DB .(1) Metode  Open(): deschide o conexiune la baza de date  Close() şi Dispose(): închid conexiunea şi eliberează toate resursele alocate pentru ea  BeginTransaction(): pentru executarea unei tranzacţii pe baza de date. II. State (enumerare de componente ConnectionState. Security User ID Numele unui user care are acces de logare pe server Password Parola corespunzătoare ID-ului specificat. Descriere Specifică furnizorul de date pentru conectarea la sursa de date. Data Source Identifică serverul. Conţine lista de parametri necesari conectării sub forma parametru=valoare. care poate fi local.Initial Catalog=SALARII. cu accesor de tip get): specifică numărul de secunde pentru care un obiect de conexiune poate să aştepte pentru realizarea conectării la server înainte de a se genera o excepţie.\\SQLEXPRESS. un domeniu sau o adresa IP.IntegratedSecurity=SSPI").8.NET Data Provider. Se poate specifica o valoare diferită de 15 în ConnectionString folosind parametrul Connect Timeout. Valoarea Timeout=0 specifică aşteptare nelimitată. Executing. separaţi prin .  ConnectionTimeout (int. 212 .  ConnectionString (String. la sfârşit se apelează Commit() sau Rollback(). read-only): returnează versiunea de server la care s–a făcut conectarea. Open. read-only): returnează numele bazei de date la care s–a făcut conectarea. unde: Database (string. read-only): returnează starea curentă a conexiunii. (implicit 15).SqlConnection co = new SqlConnection(". Valorile posibile: Broken. Connecting. read-only): returnează furnizorul de date ServerVersion (string. Este necesară pentru a arăta unui utilizator care este baza de date pe care se face operarea Provider (de tip string. Initial specifică numele bazei de date.Initial Catalog=SALARII. cu accesori de tip get şi set ) defineşte un şir care permite identificarea tipului şi sursei de date la care se face conectarea şi eventual contul şi parola de acces.IntegratedSecurity=SSPI").. Connect Timeout=30.

Comenzi Clasele din categoria Command (SQLCommand.Data.4. Obiectele de tip SQLCommand pot fi utilizate într-un scenariu ce presupune deconectarea de la sursa de date dar şi în operaţii elementare care presupun obţinerea unor rezultate imediate.8. ChangeDatabase(): se modifică baza de date la care se vor face conexiunile.4.8. Aceste clase implementează interfaţa IDbCommand. O comandă se poate executa numai după ce s-a stabilit o conxiune cu baza de date corespunzătoare. Data.  InfoMessage: apare când furnizorul trimite un avertisment sau un mesaj către client. DELETE. Text (comandă SQL obişnuită). II.5. Dacă se depăşeste acest timp.Data. Handlerul corespunzător (de tipul delegat StateChangeEventHandler) spune între ce stări s-a făcut tranziţia.PrefixTransaction): permite accesul la obiectul de tip tranzacţie care se cere a fi executat pe sursa de date.  Parameters (System. II.[Provider].) conţin date referitoare la o comandă SQL (SELECT.PrefixParameterCollection): returnează o colecţie de parametri care s-au transmis comenzii.PrefixConnection): conţine obiectul de tip conexiune folosit pentru legarea la sursa de date.[Provider].  CreateCommand(): creează o comandă (un obiect de tip Command) validă asociată conexiunii curente.(2) Evenimente  StateChange: apare atunci când se schimbă starea conexiunii. INSERT. OleDbCommand etc.  Transaction (System. II. [Provider]. Valorile pot fi: StoredProcedure (apel de procedură stocată). TableDirect (numai pentru OleDb)  Connection (System. II.8.3. Noua bază de date trebuie să existe pe acelaşi server ca şi precedenta.  CommandType (enumerare de componente de tip CommandType): reprezintă tipul de comandă care se execută pe sursa de date. DataReader 213 . Ca urmare a interogării unei baze de date se obţin obiecte din categoriile DataReader sau DataSet. atunci se generează o excepţie.8. UPDATE) şi metode pentru executarea unei comenzi sau a unor proceduri stocate.  CommandTimeout (int): reprezintă numărul de secunde care trebuie să fie aşteptat pentru executarea comenzii. Vom exemplifica utilizarea obiectelor de tip Command în operaţii ce corespund acestui caz.(1) Proprietăţi  CommandText (String): conţine comanda SQL sau numele procedurii stocate care se execută pe sursa de date.

8. GetString() returnează valoarea unui câmp specificat. Overhead-ul asociat este foarte mic (overhead generat cu inspectarea rezultatului şi a scrierii în baza de date). Dacă într-o aplicaţie este nevoie doar de informaţii care vor fi citite o singura dată. GetFloat(). sau pot fi preluate de la sursă (dintr-un obiect din categoria DataAdapter) şi înglobate în aplicaţia curentă (sub forma unui obiect din categoria DataSet).) implementează interfaţa IDataReader. returnând false numai dacă aceasta nu există. Datorită faptului că citeşte doar înainte (forward-only) permite acestui tip de date să fie foarte rapid în citire.read-only).verifică dacă reader-ul conţine cel puţin o înregistrare  Item (indexator de câmpuri)  FieldCount-returnează numărul de câmpuri din înregistrarea curentă II. Toate clasele DataReader (SqlDataReader. Un obiect DataReader nu are constructor. II. read-only).5. Metoda clasică de a citi informaţia dintr-un DataReader este de a itera intr-o bucla while. GetInt16(). sau rezultatul unei interogări este prea mare ca sa fie reţinut în memorie (caching) DataReader este soluţia cea mai bună. de reţinut că iniţial poziţia curentă este înaintea primei înregistrări. Dacă se doreşte modificarea datelor la sursă. GetChars() citirea unor octeţi/caractere dintr-un câmp de date binar  GetDataTypeName(). conexiunea trebuie să fie activă. GetValue(). GetChar(). 214 .Datele pot fi explorate în mod conectat (cu ajutorul unor obiecte din categoria DataReader). Clasele DataReader permit parcurgerea într-un singur sens a sursei de date.8. aceasta citeşte un singur rând din tabelul rezultat. DataReader obţine datele într-un stream secvenţial.(1) Proprietăţi:  IsClosed (boolean.  GetBoolean(). din înregistrarea curentă  GetBytes().returneză true dacă obiectul este deschis şi fals altfel  HasRows (boolean. GetName() returnează tipul/numele câmpului specificat  IsDBNull() returnează true dacă în câmpul specificat prin index este o valoare NULL  NextResult()determină trecerea la următorul rezultat stocat în obiect (vezi exemplul)  Read() determină trecerea la următoarea înregistrare. trebuie să preceadă închiderea conexiunii. GetInt64(). pe toată durata lucrului cu un obiect de tip DataReader. Evident.5. OleDbDataReader etc. Pentru a citi aceste informaţii trebuie apelată metoda Read. GetDecimal(). GetDateTime(). se va utiliza ansamblul DataAdapter + DataSet. GetInt32(). ci se obţine cu ajutorul unui obiect de tip Command şi prin apelul metodei ExecuteReader() (vezi exerciţiile de la capitolul anterior). fără posibilitate de modificare a datelor la sursă. GetByte().(2) Metode:  Close() închidere obiectului şi eliberarea resurselor. GetDouble().

 ExecuteNonQuery() execută o comandă care nu returnează un set de date din baza de date. 215 .reader[2].ExecuteNonQuery().II.Close(). co).Close().Integrated Security=SSPI"). SqlCommand() Constructori şi metode asociate obiectelor de tip comandă SqlCommand cmd = new SqlCommand().Integrated Security=SSPI").  ExecuteReader() execută comanda şi returnează un obiect de tip DataReader. Exemplul 4: se va şterge înregistrarea cu numele PREDA şi se va returna un obiect afectat SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS. SqlCommand cmd = new SqlCommand("DELETE FROM SALAR_ANGAJAT WHERE nume = ’PREDA’". SqlCommand cmd = new SqlCommand("SELECT * FROM SALAR_ANGAJAT".ReadLine().WriteLine(String.Format("\t{0}\t{1}\t{2} \t {3} \t {4}". Console.8. reader.ReadLine().ExecuteReader(). SqlConnection con ) SqlCommand cmd = new SqlCommand("DELETE FROM SALAR_ANGAJAT WHERE nume = ’PREDA’". Console.  Cancel() opreşte o comandă aflată în executare.Initial Catalog=SALARII.co).Open().  Dispose() distruge obiectul comandă.reader[4])). while (reader. UPDATE. SqlCommand(string CommandText. DELETE. SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS. SqlDataReader reader = cmd.6. Exemplul 5: Se obţine conţinutul tabelei într-un obiect de tip SqlDataReader.Open().Initial Catalog=SALARII. se returnează numărul de înregistrări afectate.Read()) Console. co.co). co.reader[1]. cmd.reader[3]. În cazul în care comanda a fost de tip INSERT. reader[0]. co.

ExecuteReader(). reader[0]. } Console. .WriteLine(" ID NUME PRENUME VECHIME"). Console.select * from telefoane". Console. Console.WriteLine(" ID NUME PRENUME TELEFON").WriteLine(String. Console. 216 . co).Read()) { Console.WriteLine(). Console.KeyInfo (returneză informaţie despre coloane şi cheia primară). Console. care descrie rezultatele şi efectul asupra bazei de date: .Initial Catalog=SALARII. . SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS.ReadLine(). Console.CloseConnection (conexiunea este închisă atunci când obiectul DataReader este închis). SqlCommand cmd = new SqlCommand("select * from salar_angajat. co.WriteLine().WriteLine(). Conţinutul ei este prezentat mai jos. De data aceasta vom afişa conţinutul ambelor tabele. reader[2]. Console.WriteLine().WriteLine("Datele din tabela TELEFOANE").NextResult()).Exemplul 6: Am construit o nouă tabelă tot în baza de date salarii numită telefoane.SqlDataReader reader = cmd. CommandBehavior. do { while (reader.SchemaOnly (returneză doar informaţie despre coloane). Metoda ExecuteReader() mai are un argument opţional de tip enumerare. reader[1]. reader[3])). } while (reader.WriteLine("Datele din tabela SALARII").Integrated Security=SSPI").Format("\t{0}\t{1}\t{2} \t {3} ".Open().

SingleRow (se returnează o singură linie).Close().SequentialAccess (pentru manevrarea valorilor binare cu GetChars() sau GetBytes()). while (rdr. Console.ExecuteReader(). SqlDataReader rdr =cmd.WriteLine(rdr["nume"]).Integrated Security=SSPI").SingleResult (se returnează un singur set de rezultate). . co.  ExecuteScalar() execută comanda şi returnează valoarea primei coloane de pe primul rând a setului de date rezultat. . Din aceasta cauză este preferată utilizarea indexatorilor de tipul string.ReadLine(). SqlCommand cmd = new SqlCommand("select * from salar_angajat".ReadLine(). Exemplul 7: cele două surse scrise mai jos sunt echivalente. } rdr. SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS. } rdr. Ele afişează datele înregistrate pe coloana NUME.. SqlDataReader rdr =cmd.Initial Catalog=SALARII. co).ExecuteReader().Integrated Security=SSPI").Close(). SqlCommand cmd = new SqlCommand("select * from salar_angajat".Open(). Console. while (rdr.Open(). sau SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS. co. co). Nu este foarte clar pentru cineva care citeşte codul care sunt coloanele afişate decât dacă s-a uitat şi în baza de date.Read()) { Console. Exemplul 8: 217 .Read()) { Console. Este folosită pentru obţinerea unor rezultate statistice. DataReader implementează şi indexatori. Indiferent că se foloseşte un index numeric sau unul de tipul string indexatorii întorc totdeauna un obiect de tipul object fiind necesară conversia.WriteLine(rdr[1]).Initial Catalog=SALARII. Valoarea indexului trebuie să fie numele coloanei din tabelul rezultat.

218 .ReadLine(). co). SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS.ExecuteScalar().8.Integrated Security=SSPI").7.Open(). 17.'EUGENIU'.1993)". II.NUME. // Instanţiem o comandă cu acestă cerere şi precizăm conexiunea SqlCommand cmd = new SqlCommand(insertString. co). Console. SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM SALAR_ANGAJAT".SALAR) values (6 . // şirul care păstrează comanda de inserare string insertString = @"insert into salar_angajat(ID. Interogarea datelor Pentru extragerea datelor cu ajutorul unui obiect SqlCommand trebuie să utilizăm metoda ExecuteReader care returnează un obiect SqlDataReader.ExecuteReader().ExecuteNonQuery(). // Apelăm metoda ExecuteNonQuery pentru a executa comanda cmd. II. // Obţinem rezultatul cererii SqlDataReader rdr = cmd.8. Console.co). Inserarea datelor Pentru a insera date într-o bază de date utilizăm metoda ExecuteNonQuery a obiectului SqlCommand .PRENUME.8.WriteLine(var). // Instanţiem o comandă cu o cerere şi precizăm conexiunea SqlCommand cmd = new SqlCommand("select salar from salar_angajat". var=(Int32) cmd.Int32 var = 0.'BARBU' .VECHIME.Initial Catalog=SALARII. co.

cmd. SqlDataReader reader = comand. SqlCommand cmd = new SqlCommand(insertString. reader.Exemplul 9: vom insera în tabela salar_angajat o nouă înregistrare şi vom afişa tot conţinutul tabelei SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS.Open().Format("\t{0}\t{1}\t{2} \t {3} \t {4}". reader[2]. co).Integrated Security=SSPI").ExecuteReader(). reader[0].8. Actualizarea datelor în tabela Exemplul 10: vom modifica numele unui angajat.Close(). SqlCommand cmd = new SqlCommand(updateString). reader[3].WriteLine(String.Initial Catalog=SALARII.//Apelăm ExecuteNonQuery pentru executarea comenzii SqlCommand comand = new SqlCommand("SELECT * FROM SALAR_ANGAJAT".ReadLine().ExecuteNonQuery(). } 219 . while (reader. co. Console.9.Open().SALAR)values (6.Close(). reader[2].PRENUME .ExecuteReader().reader[0]. co). reader[3]. cmd.'EUGENIU'.Read()) Console. }} SqlCommand comand = new SqlCommand("SELECT * FROM SALAR_ANGAJAT".Integrated Security=SSPI"). Console.Connection = co. co. string insertString = @"insert into salar_angajat(ID .Close(). SqlDataReader reader = comand.VECHIME .NUME . string updateString = @"update SALAR_ANGAJAT set NUME = 'BIBIRE' where NUME = 'BARBU'". } II.ReadLine().Read()) Console.reader. reader[4])).WriteLine(String. reader[1]. while (reader. try {co.'BARBU'.ExecuteNonQuery().Initial Catalog=SALARII. reader[4])).1993)".Format("\t{0}\t{1}\t{2} \t {3} \t {4}".Open().17.} finally {if (co != null) { co. din BARBU în BIBIRE SALAR_ANGAJAT şi vom afişa tot conţinutul tabelei SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS. reader[1]. co). // Stabilim conexiunea cmd.

Integrated Security=SSPI"). SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS.ReadLine(). reader[3].WriteLine(" RON"). // Instanţiem o comandă SqlCommand cmd = new SqlCommand(). Int32 var = 0.WriteLine(" ANI"). reader[4])).ExecuteScalar().Write(" SUMA SALARIILOR TUTUROR ANGAJATILOE ESTE: "). Int32 suma = 0.ExecuteNonQuery().Write(suma). SqlCommand comand = new SqlCommand("SELECT * FROM SALAR_ANGAJAT".Write(var).Connection = co. reader[2]. reader[1].Read()) Console. Ştergerea datelor Se utilizează aceeaşi metodă ExecuteNonQuery. SqlCommand comand1 = new SqlCommand("select MAX(VECHIME) FROM SALAR_ANGAJAT". Executăm comanda cmd. Exemplul 11: vom şterge înregistrarea cu numele BIBIRE din tabela SALAR_ANGAJAT şi vom afişa tot conţinutul tabelei SqlConnection co = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS. co. // şirul care păstrează comanda de ştergere string deleteString = @"delete from SALAR_ANGAJAT where NUME = 'BIBIRE'". Console. var = (Int32)comand1.Format("\t{0}\t{1}\t{2} \t {3} \t {4}".ExecuteReader().Initial Catalog=SALARII. } Exemplul 12: Realizaţi o conexiune la baza de date SALAR_ANGAJAT şi afişaţi cea mai mare vechime şi suma tuturor salariilor înregistrate. Console. co. 220 .Write(" CEA MAI MARE VECHIME A UNUI ANGAJAT ESTE DE :"). SqlDataReader reader = comand. // Setăm proprietatea Connection cmd.Integrated Security=SSPI"). SqlCommand comand2 = new SqlCommand("select SUM(SALAR) FROM SALAR_ANGAJAT".Initial Catalog=SALARII.CommandText = deleteString. while (reader. // .co). // Setăm proprietatea CommandText cmd. reader. reader[0].Open().8. Console.Close(). co). Console.II. Console.Open().ExecuteScalar().ReadLine().WriteLine(String. co). Console. suma = (Int32)comand2. Console.10. Console.

WriteLine("AFISARE DUPA INSERT"). number_inregistrari). rdr[1].Exemplul 12: Realizaţi funcţii care să implementeze operaţiile elementare asupra unei baze de date şi verificaţi funcţionalitatea lor. scd.Close(). public program() { conn = new SqlConnection("DATA SOURCE=DANAD90FDEF1A8\\SQLEXPRESS.Close(). Console. rdr[2]. Console.WriteLine("AFISARE DUPA DELETE"). inserarea unei noi valori. scd.WriteLine(String. Console. SqlCommand cmd = new SqlCommand("select * from salar_angajat".Integrated Security=SSPI"). Console.ReadData(). scd. Console. conn).GetNumberOfRecords(). int number_inregistrari = scd. scd. } if (conn != null) { conn.ExecuteReader(). rdr = cmd.ReadLine(). scd.WriteLine("AFISARE DUPA UPDATE"). } finally { if (rdr != null) { rdr. rdr[4])).  conexiunea la baza de date class program { SqlConnection conn. }  funcţia de citire şi afişare a datelor public void ReadData() { SqlDataReader rdr = null.Read()) Console.WriteLine("Numarul de inregistrari: {0}".Initial Catalog=SALARII.DeleteData().Insertdata(). Console. ştergerea unor valori.WriteLine("SALARII ANGAJATI"). actualizare static void Main() { program scd = new program(). try { conn.Format("\t{0}\t{1}\t{2} \t {3} \t {4}".UpdateData().ReadData(). rdr[0].Open(). scd. while (rdr. rdr[3].ReadData(). } } }  funcţia care realizează inserarea unei noi valori 221 . scd.}  apelarea din funcţia main a funcţiilor care vor realiza afişarea datelor.ReadData().

} } return count. string insertString = @"insert into salar_angajat(ID . conn).Close().Open().'EUGENIU'. } finally { if (conn != null) { conn.} finally { if (conn != null) { conn.Close(). cmd.Open().public void Insertdata() { try {conn.17.1993)".Close(). string deleteString = @"delete from SALAR_ANGAJAT where NUME = 'BARBU'". try { conn.ExecuteScalar().CommandText = deleteString. } finally { if (conn != null) { conn.Close(). } } }  funcţia care numără înregistrările din tabelă public int GetNumberOfRecords() { int count = -1. string updateString = @"update SALAR_ANGAJAT set PRENUME = 'MARIA' where PRENUME = 'DANIELA'". cmd. SqlCommand cmd = new SqlCommand(updateString). cmd. } } }  funcţia care şterge una sau mai multe înregistrări în funcţie de condiţia impusă public void DeleteData() { try { conn. conn).Connection = conn.ExecuteNonQuery(). } finally { if (conn != null) { conn.ExecuteNonQuery().Connection = conn.Open().SALAR)values (6. } }}  funcţia care actualizează anumite valori specificate public void UpdateData() { try { conn.PRENUME . } 222 . SqlCommand cmd = new SqlCommand(insertString. SqlCommand cmd = new SqlCommand("select count(*) from SALAR_ANGAJAT". cmd. count = (int)cmd.ExecuteNonQuery(). cmd.NUME . cmd.'BARBU'.Open().VECHIME . SqlCommand cmd = new SqlCommand().

conn).11. DataAdapter adaugă coloana la schema tablei AddWithKey – se adaugă coloana şi informaţii relativ la cheia primară Ignore .Fill(ds. InsertCommand.se ignoră lipsa coloanei respective." salar_angajat ").implicit. de.//transferă datele în datasetul ds sub forma unei tabele locale numite telefoane datele în datasetul ds sub forma unei Proprietăţi  DeleteCommand. Foloseşte serviciile unui obiect DataAdapter pentru a-şi procura datele şi trimite modificările înapoi către baza de date. Ele gestionează automat conexiunea cu baza de date astfel încât conexiunea să se facă numai atunci când este imperios necesar.8. În exemplul următor se preiau datele din tablele salar_angajat şi telefoane: SqlDataAdapter de=new SqlDataAdapter("SELECT nume.telefon FROM telefoane”. Poate avea următoarele valori: Add . conţin comenzile ce se execută pentru selectarea sau modificarea datelor în sursa de date. ceea ce duce la pierdere de date 223 . conn). acelaşi folosit şi pentru transferul datelor. Clasele DataAdapter generează obiecte care funcţionează ca o interfaţă între sursa de date şi obiectele DataSet interne aplicaţiei. SelectCommand. Datele sunt stocate de un DataSet în format XML. DataAdapter şi DataSet Folosirea combinată a obiectelor DataAdapter şi DataSet permite operaţii de selectare. permiţând prelucrări pe baza de date.//transferă tabele locale numite salariu_angajat SqlDataAdapter dp=new SqlDataAdapter("SELECT nume. modificare şi adăugare la baza de date. ştergere. Un obiect DataSet este de fapt un set de tabele relaţionate.  MissingSchemaAction (enumerare) determină ce se face atunci când datele aduse nu se potrivesc peste schema tablei în care sunt depuse. UpdateCommand (Command)." telefoane ").Fill(ds.prenume FROM salar_angajat”.II. dp.

apelând metoda Fill  procesarea datelor din DataSet folosind numele tabelelor stabilite la umplere. În exemplul anterior avem un DataSet gol şi avem nevoie de un DataAdapter pentru a-l popula. Un obiect DataAdapter conţine mai multe obiecte Command (pentru inserare. populează DataSet-ul. scrie modificările din DataSet în baza de date. Constructorul unui DataSet nu necesită parametri. Relations (colecţie de obiecte de tip DataRelation pentru memorarea legăturilor părinte–copil) şi ExtendedProperties ce conţine proprietăţi definite de utilizator. Metode  Constructori:SqlDataAdapter()|SqlDataAdapter(obiect_comanda)| SqlDataAdapter(string_comanda. De exemplu DataAdapter realizează următoarele operaţiuni atunci când trebuie sa populeze un DataSet:deschide conexiunea. DataSet dsProduse = new DataSet (). conexiune). eventual a numelui tablei din acest DataSet.Tables[0]. ds. Un obiect CommandBuilder poate construi automat o combinaţie de comenzi ce reflectă modificările efectuate. update. UPDATE şi DELETE. ds.se generează o excepţie de tipul InvalidOperationException. sau indexarea acestora. Intre aceste operaţii în DataSet se poate scrie sau citi.  Update() permite transmiterea modificărilor efectuate într-un DataSet către baza de date. DataAdapter deschide o conexiune doar atunci când este nevoie şi o închide imediat aceasta nu mai este necesară.Error .Tables["salar_angajat"].închide conexiunea şi următoarele operaţiuni atunci când trebuie sa facă update pe baza de date: deschide conexiunea. închide conexiunea. numărul de înregistrare cu care să se înceapă popularea (prima având indicele 0) şi numărul de înregistrări care urmează a fi aduse. Crearea unui obiect de tipul DataSet se face folosind operatorul new. Permite specificarea obiectului DataSet în care se depun datele. Există totuşi o supraîncărcare a acestuia care primeşte ca parametru un string şi este folosit atunci când trebuie să se facă o serializare a datelor într-un fişier XML. Aşadar. 224 . Un DataSet este format din Tables (colecţie formată din obiecte de tip DataTable este compus la rândul lui DataTable. Scenariul uzual de lucru cu datele dintr-o tabelă conţine următoarele etape:  popularea succesivă a unui DataSet prin intermediul unuia sau mai multor obiecte DataAdapter.  Fill() permite umplerea unei tabele dintr-un obiect DataSet cu date. Între operaţiunea de populare a DataSet-ului şi cea de update conexiunile sunt închise. delete şi select) şi un obiect Connection pentru a citi şi scrie date. dintr-o colecţie de DataRow şi DataColumn).Tables[1]  actualizarea datelor prin obiecte comandă corespunzătoare operaţiilor INSERT. ds.

fie folosind obiecte de tipul CommandBuilder. Prin intermediul constructorului putem instanţia doar comanda de interogare. daSALAR.Fill (dsNUME. co). dar nu şi deschisă.DataMembers = "NUME". În cazul în care nu sunt specificate numele tabelelor. DataGrid dgANGAJAT = new DataGrid(). Cel de-al doilea parametru (string) reprezintă numele tabelului (nu numele tabelului din baza de date. La iniţializarea unui CommandBuilder se apelează un constructor care primeşte ca parametru un adapter. dgANGAJAT. "NUME"). Atunci când trebui ca sa facem comenzi care vor folosi mai multe tabele este recomandata construirea separată a comenzilor şi apoi ataşarea lor adapterului folosind proprietăţi. Comanda SQL specifică cu ce date va fi populat un DataSet. SALAR SALARIU_ANGAJAT". SqlCommandBuilder are nu poate construi decât comenzi simple şi care se aplica unui singur tabel. Instanţierea celorlalte se face fie prin intermediul proprietăţilor pe care le expune DataAdapter. Actualizarea se face prin apelul metodei Update.Net . Un DataSet poate fi folosit ca sursă de date pentru un DataGrid din Windows Forms sau ASP.Update (dsNUME. În exemplul următor va fi populat DataSet-ul dsNUME. 225 . Popularea DataSet-ului se face după ce am construit cele două instanţe: daSALAR. .. pentru care vor fi construite comenzile. daSALAR.DataSource = dsNUME. Table2. dgANGAJAT. SqlDataAdapter daSALAR = new SqlDataAdapter ("SELECT NUME. SqlCommandBuilder cmdBldr = new SqlCommandBuilder (daSALAR). acestea vor fi adăugate în DataSet sub numele Table1.. DataAdapter-ul va deschide conexiunea la apelul metodelor Fill şi Update. iar conexiunea co trebuie să fi fost creată anterior. ci al tabelului rezultat în DataSet) care va fi creat. Scopul acestui nume este identificarea ulterioară a tabelului. După ce au fost făcute modificări într-un DataSet acestea trebuie scrise şi în baza de date. "NUME").În exemplul următor construim un obiect de tipul DataAdapter.

iar în dreptul ei o casetă de text.să afişeze cea mai mică vechime . VECHIME. cinci etichete(ID. .să afişeze cel mai mare salar .insereze una sau mai multe înregistrări. public partial class Form1 : Form { int nrmodificari = 0.II. . Din meniul File al aplicaţiei Microsoft Visual C# 2008 Express Edition alegeţi New Project/Windows Forms Application. Noi ne-am propus să creăm o aplicaţie care să: . PRENUME. Pe formular va trebui să „trageţi” un buton (INSERARE). SALAR) pe care o puteţi popula cu câteva înregistrări.să afişeze înregistrările în ordine lexicografică Pentru a realiza şi voi acelaşi lucru va trebui să parcurgeţi paşii explicaţi în continuare.să şteargă una sau mai multe înregistrări. .să afişeze permanent numărul de astfel de modificări efectuate.să afişeze conţinutul tabelei după fiecare modificare. cinci casete de text poziţionate sub fiecare etichetă.9. . NUME. inserări) şi conexiunea la baza de date. public Form1() { InitializeComponent().să calculeze suma salariilor din tabelă . SqlConnection co. SALAR). Aplicaţie finală Pentru a realiza această aplicaţie trebuie să creaţi o bază de date (noi am numit-o salarii) bază în care trebuie să creaţi o tabelă (noi am anumit-o salar_angajat) cu cinci câmpuri (ID. 226 . PRENUME. VECHIME. Urmăriţi imaginea din figura de mai jos: În sursa din spatele formularului declaraţi o variabilă de tip int nrmodificari care va contoriza permanent numărul de modificări aduse tabelei (ştergeri. NUME. o etichetă în care să introduceţi textul „NUMĂR DE MODIFICĂRI”.

textBox6.vechime şi salar). nrmodificari = nrmodificari+cmd.Text+"'. 227 .vechime. private void button1_Click(object sender.'"+textBox5.'"+textB ox4.ToString(nrmodificari).prenume.prenume.Database=dana. patru etichete (pentru nume.Text =Convert. EventArgs e) { string insertsql. co). cod care vă va permite afişarea celor patru câmpuri din tabelă.salar) values ('". } Source=DANA- Executaţi ciclk dublu pe butonul INSERARE şi completaţi sursa lui cu instrucţiunile care vor permite inserarea unor înregistrări noi în tabelă.nume.insertsql+=textBox1. iar în sursa butonului „AFISARE” să completaţi codul de mai jos. insertsql="insert into salar_angajat (id.Text+"'.Text+"'.").Open(). SqlCommand cmd = new SqlCommand(insertsql.} } Pentru a vizualiza şi conţinutul tabelei pe formular va trebui să mai „trageţi” un buton „AFISARE” .co = new SqlConnection(@"Data D90FDEF1A8\SQLEXPRESS.Trusted_Connection=yes. co.'"+textBox3.Text+"')".Text+"'. Numărul de inserări îl veţi putea vizualiza în caseta de text asociată etichetei cu numele „NUMĂR DE MODIFICĂRI”.'"+textBox2.ExecuteNonQuery().

Text = label7. DataSet ds = new DataSet(). şi mai adăugaţi un buton pe care noi lam numit „STERGERE”. EventArgs e) { string deletesql.Text = label9.Text = "PRENUME".private void button2_Click(object sender.Text = label8.Text = "NUME". label10. label7. label8.Text + "\n"+r["prenume"] + "\n". SqlCommand cmd = new SqlCommand(selectSQL. label8. deletesql += textBox7. label9.ExecuteNonQuery(). SqlDataAdapter adapter = new SqlDataAdapter(cmd).Text = "SALAR". SqlCommand cmd = new SqlCommand(deletesql. } Pentru a obţine suma salariilor din tabelă va trebui să completaţi formularul în mod design cu încă un buton cel pe care noi l+am numit SUMA SALARII. co).Fill(ds. EventArgs e) { string selectSQL = "SELECT * FROM salar_angajat".Text+ "'". nrmodificari = nrmodificari + cmd. label10.ToString(nrmodificari). pe care o veţi poziţiona în dreptul etichetei. o etichetă în care va trebui să introduceţi textul „INTRODUCETI NUMELE ANGAJATULUI CE TREBUIE STERS” şi o casetă de text. în dreptul lui să adăugaţi o 228 . co).Rows) { label7.Text +"\n"+ r["vechime"] + "\n". adapter.Text +"\n" + r["nume"] + "\n".Tables["salar_angajat"]. private void button3_Click(object sender. deletesql = "delete from salar_angajat where nume='". "salar_angajat").Text = "VECHIME". textBox6.Text = label10. label9.Text + "\n"+r["salar"] + "\n". } } Vă întoarceţi acum pe formular în mod design. Executaţi clic dublu pe butonul STERGE şi completaţi sursa cu codul care vă va permite ştergerea unui angajat al cărui nume va fi preluat din caseta de text.Text = Convert. foreach (DataRow r in ds.

textBox8.casetă de text şi să completaţi sursa butonului cu codul care vă va permite obţinerea sumei salariilor înregistrate în tabelă apelând funcţia SUM.ToString(suma). casete de text şi etichete.Text = Convert. co). private void button4_Click(object sender. VECHIME. prin : ‐ modificarea poziţiilor celor deja existente ‐ adăugarea a patru etichete pe care vor fi introduse textele NUME. } În acest moment pregătiţi suprafaţa formularului pentru includerea unor noi butoane. suma= (int)cmd. SALAR 229 .ExecuteScalar(). EventArgs e) { int suma. PRENUME. SqlCommand cmd = new SqlCommand("select SUM(SALAR) FROM SALAR_ANGAJAT".

Tables["salar_angajat"]. label10.Adăugaţi două butoane şi două casete de text pe care încercaţi să le poziţionaţi sub butonul SUMA SALARII. textBox10. EventArgs e) { int min.ToString(max). SqlCommand cmd = new SqlCommand("select max(SALAR) FROM SALAR_ANGAJAT". label9.Text = "". Textul celor două butoane va fi: Cea mai mica vechime. } În dreptul butonului AFISARE adăugaţi un buton pe care veţi insera textul: AFISARE IN ORDINE LEXICOGRAFICA. adapter. co). textBox9. "salar_angajat"). private void button1_Clic_1(object sender.ExecuteScalar().Text = label8.ExecuteScalar(). EventArgs e) { int max. max = (int)cmd. SqlCommand cmmd = new SqlCommand(selectSQL. 230 .Text = "". label7. co). SqlDataAdapter adapter = new SqlDataAdapter(cmmd).Rows) { label7.Text = Convert. foreach (DataRow r in ds.Fill(ds. co). SqlCommand cmd = new SqlCommand("select min(vechime) FROM SALAR_ANGAJAT". respectiv Cel mai mare salariu. DataSet ds = new DataSet().Text = label7. Sursele din spatele celor două butoane vor fi cele din exemplele de mai jos: private void button5_Click(object sender. min = (int)cmd. label8.ToString(min). } private void button6_Click(object sender.Text = Convert. label8.Text = "". şi completaţi sursa lui cu următorul cod.Text + "\n" + r["prenume"] + "\n".Text + "\n" + r["nume"] + "\n". EventArgs e) { string selectSQL = "select * FROM SALAR_ANGAJAT ORDER BY NUME ASC".Text = "".

Text + "\n" + r["salar"] + "\n". iar dacă pe parcurs mai doriţi să adăugaţi sau să modificaţi aplicaţia aţi observat că acest lucru este posibil.Text = label10.Text + "\n" + r["vechime"] + "\n". label10. Totul este să vă stabiliţi priorităţile înainte de a vă apuca de lucru. Toate funcţiile şi comenzile SQL prezentate în acest capitol se pot regăsi într-o aplicaţie de acest gen.label9.Text = label9. 231 . } } În acest moment puteţi spune că aţi creat o aplicaţie care vă ajută să gestionaţi într-o oarecare măsură o tabelă a unei baze de date.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->