tipuri generice in c#

18
Tipuri generice in C#

Upload: kostys1

Post on 26-Aug-2014

250 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Tipuri Generice in C#

Tipuri generice in C#

Page 2: Tipuri Generice in C#

Introducere

• Structuri de date type-safe;• Reutilizarea algoritmilor de procesare fara

cunoasterea tipului de date;

Page 3: Tipuri Generice in C#

Problema

//solutie object-based public class Stack { object[] m_Items; public void Push(object item)

{...} public object Pop() {...} }

//instante de tipuri diferite

Page 4: Tipuri Generice in C#

Solutie 1public class Stack {

readonly int m_Size; int m_StackPointer = 0; object[] m_Items; public Stack():this(100) { } public Stack(int size) { m_Size = size; m_Items = new object[m_Size]; } public void Push(object item) {

if(m_StackPointer >= m_Size) throw new StackOverflowException(); m_Items[m_StackPointer] = item;

m_StackPointer++; } public object Pop() { m_StackPointer--; if(m_StackPointer >= 0) { return m_Items[m_StackPointer]; }

else { m_StackPointer = 0; throw new InvalidOperationException("Cannot pop an empty stack"); } } }

Page 5: Tipuri Generice in C#

UtilizareStack stack = new Stack(); stack.Push(1); stack.Push(2);

int number = (int)stack.Pop();

Page 6: Tipuri Generice in C#

Probleme1. De performanta: -la tipuri valoare trebuie folosit procedeul boxing/unboxing;-la tipuri referinta trebuie conversie explicita:Stack stack = new Stack(); stack.Push("1");

string number = (string)stack.Pop(); 2. Type-safety:Stack stack = new Stack(); stack.Push(1); //se compileaza, dar la executie apare exceptie

string number = (string)stack.Pop();

Page 7: Tipuri Generice in C#

Solutie alternativa• Cate a structura pentru fiecare tip• IntStack, StringStack, …• Problema: actiune error-prone (repetitiva). Copy+paste introduce totdeauna

erori!!!! Cand se repara o eroare in codul pentru IntStack, acest lucru trebuie facut pentru toate celelalte,…

Page 8: Tipuri Generice in C#

Ce sunt tipurile generice

• Clase type-safe cu tipuri de date generice;//T este parametru tip-genericpublic class Stack<T> { T[] m_Items; public void Push(T item) {...} public T Pop() {...} } Stack<int> stack = new Stack<int>(); stack.Push(1); stack.Push(2); int number = stack.Pop();

AVANTAJ: algoritmii interni raman neschimbati pentru toate tipurile de date

Page 9: Tipuri Generice in C#

Clase si structuri genericepublic struct Point<T> { public T X; public T Y; } Point<int> point1; point1.X = 1;

point1.Y = 2; Point<double> point2; point2.X = 1.2;

point2.Y = 3.4;

Page 10: Tipuri Generice in C#

Operatorul default()public T Pop() {

m_StackPointer--; if(m_StackPointer >= 0) {

return m_Items[m_StackPointer]; } else { m_StackPointer = 0; return default(T); }

}

//default(T) intoarce valoare default a tipului T

Page 11: Tipuri Generice in C#

Mai multi parametrii//lista cu legaturiclass Node<K,T> {

public K Key; public T Item; public Node<K,T> NextNode; public Node() {

Key = default(K); Item = defualt(T); NextNode = null;

} public Node(K key,T item,Node<K,T> nextNode) {

Key = key; Item = item; NextNode = nextNode;

} } public class LinkedList<K,T> {

Node<K,T> m_Head; public LinkedList() { m_Head = new Node<K,T>();

} public void AddHead(K key,T item) { Node<K,T> newNode = new Node<K,T>(key,item,m_Head.NextNode); m_Head.NextNode = newNode; }

}

Page 12: Tipuri Generice in C#

Mai multi parametriiFiecare nod contine o cheie (de tip generic K) si o valoare (de tip generic T);Utilizare:

LinkedList<int,string> list1= new LinkedList<int,string>();

list1.AddHead(123,"AAA");

LinkedList<DateTime,string> list2 = new LinkedList<DateTime,string>();

list2.AddHead(DateTime.Now,"AAA");

Page 13: Tipuri Generice in C#

Alias pentru combinatii particulare de tipuri

using List = LinkedList<int,string>; class ListClient {

static void Main(string[] args) { List list = new List();

list.AddHead(123,"AAA"); }

} //scope: la nivel de fisier in care apare

Page 14: Tipuri Generice in C#

Constrangeri pentru tipurile generice

1. Constr. la derivare: parametrul generic este derivat dintr-o superclasa sau interfatapublic class LinkedList<K,T> { T Find(K key) {...} //cautarea unei valori dupa cheiepublic T this[K key] { //indexare dupa cheie

get{return Find(key);} }

} //nu se compileaza in acest momentT Find(K key) {

Node<K,T> current = m_Head; while(current.NextNode != null) { if(current.Key == key) //nu se compileaza

break; else current = current.NextNode; } return current.Item; }

Page 15: Tipuri Generice in C#

public interface IComparable { int CompareTo(object obj);

} public class LinkedList<K,T> where K : IComparable { T Find(K key) { Node<K,T> current = m_Head; while(current.NextNode != null) {

if(current.Key.CompareTo(key) == 0) break; else current = current.NextNode; } return current.Item; } //Restul implementarii

}

Page 16: Tipuri Generice in C#

Alte combinatii1.public class MyBaseClass {...} public class LinkedList<K,T> where K : MyBaseClass {...}

2. public class MyClass<T,U> where T : U {...} 3. public interface IMyInterface {...} public class MyClass<T> where T : IMyInterface {...}

MyClass<IMyInterface> obj = new MyClass<IMyInterface>();

Page 17: Tipuri Generice in C#

Constrangere Constructorclass Node<K,T> where T : new() { public K Key; public T Item; public Node<K,T> NextNode; public Node() { Key = default(K); Item = new T(); NextNode = null; } }//tipul T trebuie sa detina constructor default

Page 18: Tipuri Generice in C#

Constrangere tip referinta/valoare

public class MyClass<T> where T : struct {...}

public class MyClass<T> where T : class {...}