Presupunem ca avem nevoie de o metoda care sa fie apelata indiferent de tipul argumentelor.
Crearea unei interfete generice
Generics reprezinta un mecanism care permite reutilizarea codului, sporind productivitatea programatorilor.
C# si CLR permit crearea interfetelor generice. Presupunem ca avem nevoie de o interfata care specifica un anumit comportament pentru un tip specificat de programator.
Exercitiu
Se citeste o propozitie (sir de caractere). Sa se determine cate vocale si consoane contine propozitia.
Analiza Programului
Se citeste propozitia caracter cu caracter. Daca este litera, se verifica daca este vocala sau consoana.
using System; namespace Exercitiu { class Program { static void Main(string[] args) { Console.WriteLine("Introduceti propozitia:"); char[] caractere = Console.ReadLine().ToCharArray(); int vocale = 0; int consoane = 0; int index = 0; while(index < caractere.Length) { if(Char.IsLetter(caractere[index])) { switch(caractere[index]) { case 'a': case 'e': case 'i': case 'o': case 'u': vocale++; break; default: consoane++; break; } } index++; } Console.WriteLine("Numarul de caractere este {0}", caractere.Length); Console.WriteLine("Numarul de consoane este {0}", consoane); Console.WriteLine("Numarul de vocale este {0}", vocale); Console.ReadLine(); } } }
Media aritmetica, geometrica si hiperbolica a trei valori reale
Sa se afiseze media aritmetica, geometrica si hiperbolica a trei valori reale.
Analiza Programului
Media aritmetica a unui set de variabile este suma acestora impartita la numarul lor.
Media geometrica se aplica numerelor reale pozitive. Se calculeaza produsul numerelor (numarul numerelor este n), apoi se extrage radicalul de ordin n.
Media hiperbolica sau media armonica se aplica numerelor reale diferite de zero.
class Program { static void Main(string[] args) { double a, b, c; Console.WriteLine("Introduceti primul numar"); if(!Double.TryParse(Console.ReadLine(), out a)) throw new FormatException("Format incorect"); Console.WriteLine("Introduceti al doilea numar"); if (!Double.TryParse(Console.ReadLine(), out b)) throw new FormatException("Format incorect"); Console.WriteLine("Introduceti al treilea numar"); if (!Double.TryParse(Console.ReadLine(), out c)) throw new FormatException("Format incorect"); Console.WriteLine("Media aritmetica a celor trei numere este: {0}", (a+b+c)/3); double prod = a * b * c; if(prod < 0) Console.WriteLine("Media geometrica se aplica doar pentru numere pozitive"); else Console.WriteLine("Media geometrica a celor 3 numere este {0}", Math.Pow(prod, (1.0/3))); if (a == 0 || b == 0 || c == 0) Console.WriteLine("Nu se poate calcula media hiperbolica"); else Console.WriteLine("Media hiperbolica a celor 3 numere este {0}", 3/(1.0/a+1.0/b+1.0/c)); Console.ReadLine(); } }
Valoare vs. referinta (I)
CLR prezinta doua tipuri de date: tip referinta si tip valoare. In urmatoarele articole vom face o analiza mai detaliata asupra celor doua categorii.
Membri
Datele si comportamentul unei clase sunt reprezentate de membrii acesteia. Exista o serie de tipuri de membri care pot fi folositi in definirea claselor:
Extract Method
De multe ori, ca sa intelegi un cod pe care il “mostenesti” sau il preiei dintr-o aplicatie, ajungi sa faci ceea ce se cheama refactoring. Ca o scurta definitie, refactoring-ul reprezinta o restructurare ce nu va schimba comportamentul software-ului, in mod vizibil. El inseamna o “curatare” a codului intr-o maniera eficienta si organizata, o serie de schimbari care va ajuta la o mai buna intelegere a codului si la identificarea unor bug-uri nedescoperite.
Deep copy in C#
Copierea datelor este una dintre cele mai comune actiuni in programare. O metoda de copiere a fost prezentata in articolul Shallow copy.
O alta metoda de copiere o reprezinta deep copy. Deep copy reprezinta o modalitate de a clona un obiect. Deep copy va creea o copie a unui obiect in acelasi mod in care o face si shallow copy, cu deosebirea ca deep copy va face o copie separata pentru fiecare camp de tip referinta, din obiectul original. Implementarea acestei metode, in C#, poate fi scrisa astfel:
using System; namespace DeepCopy { class Program { /// <summary> /// Clasa Student /// </summary> class Student { public string Name { get; set; } public Info Info { get; set; } public Student DeepCopy() { //obtine o copie a membrilor obiectului var other = (Student)this.MemberwiseClone(); //pentru tipul referinta, copiaza obiectul referintiat other.Info = new Info(other.Info.Id); return other; } } /// <summary> /// Clasa Info /// </summary> class Info { public int Id { get; set; } public Info(int id) { Id = id; } } static void Main(string[] args) { //creeaza un obiect var s = new Student(); s.Name = "Marius"; s.Info = new Info(10); //creeaza o copie var s2 = s.DeepCopy(); //va afisa Marius Console.WriteLine(s2.Name); //va afisa 10 Console.WriteLine(s2.Info.Id); //modific valoarea obiectului s.Name = "Bogdan"; s.Info.Id = 100; //va afisa Marius Console.WriteLine(s2.Name); //va afisa 10 Console.WriteLine(s2.Info.Id); Console.ReadLine(); } } }
Deep copy mai poate fi implementata prin serializare sau cu ajutorul interfetei ICloneable.
Clasa Object
Despre .Net Framework putem spune ca reprezinta o biblioteca ce contine o multitudine de clase pe care le putem folosi intr-o aplicatie dezvoltata in C#. Toate aceste clase mostenesc Object.
Shallow copy in C#
Una din metodele pentru copierea unui obiect o reprezinta shallow copy. Ea consta in crearea unui nou obiect si copierea membrilor, care nu sunt statici, ale obiectului curent catre un nou obiect.
Clasa Object contine o metoda de tip protected numita MemberwiseClone.
In cazul in care campurile sunt de tip valoare, copierea are loc bit cu bit, acesta fiind cel mai fericit caz. In cazul in care campurile sunt de tip referinta, referinta este copiata, dar obiectul referentiat, nu. Exemplu:
using System; namespace MemberWiseExample { /// <summary> /// Clasa Student /// </summary> class Student { public string Name { get; set; } public Info Info { get; set; } public Student ShallowCopy() { return (Student)this.MemberwiseClone(); } } /// <summary> /// Clasa Info /// </summary> class Info { public int Id { get; set; } public Info(int id) { Id = id; } } class Program { static void Main(string[] args) { //se creeaza un obiect de tip Student Student s = new Student (); s.Name = "Marius"; s.Info = new Info(1); //se creeaza un obiect de tip student prin copia primului obiect Student s2 = s.ShallowCopy(); //Marius Console.WriteLine(s2.Name); //1 Console.WriteLine(s2.Info.Id); s.Name = "Bogdan"; //Bogdan Console.WriteLine(s.Name); //Marius Console.WriteLine(s2.Name); s.Info.Id = 34; //34 Console.WriteLine(s.Info.Id); //34 Console.WriteLine(s2.Info.Id); Console.ReadLine(); } } }
Shallow copy mai este denumita si memberwise copy. Se recomanda pentru cresterea performantei si in conditiile in care obiectul nu are membri care se modifice frecvent.