Tipuri Generice in C#

download

of 18

  • date post

    26-Aug-2014
  • Category

    Documents
  • view

    33
  • download

    0

Embed Size (px)

transcript

<p>Tipuri generice in C#</p> <p>Introducere Structuri de date type-safe; Reutilizarea algoritmilor de procesare fara cunoasterea tipului de date;</p> <p>Problema//solutie object-based public class Stack { object[] m_Items; public void Push(object item) {...} public object Pop() {...} } //instante de tipuri diferite</p> <p>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 &gt;= m_Size) throw new StackOverflowException(); m_Items[m_StackPointer] = item; m_StackPointer++; } public object Pop() { m_StackPointer--; if(m_StackPointer &gt;= 0) { return m_Items[m_StackPointer]; } else { m_StackPointer = 0; throw new InvalidOperationException("Cannot pop an empty stack"); } } }</p> <p>UtilizareStack stack = new Stack(); stack.Push(1); stack.Push(2); int number = (int)stack.Pop();</p> <p>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();</p> <p>2. Type-safety: Stack stack = new Stack(); stack.Push(1); //se compileaza, dar la executie apare exceptie string number = (string)stack.Pop();</p> <p>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,</p> <p>Ce sunt tipurile generice Clase type-safe cu tipuri de date generice;//T este parametru tip-generic public class Stack { T[] m_Items; public void Push(T item) {...} public T Pop() {...} } Stack stack = new Stack(); stack.Push(1); stack.Push(2); int number = stack.Pop();AVANTAJ: algoritmii interni raman neschimbati pentru toate tipurile de date</p> <p>Clase si structuri genericepublic struct Point { public T X; public T Y; } Point point1; point1.X = 1;</p> <p>point1.Y = 2;Point point2; point2.X = 1.2; point2.Y = 3.4;</p> <p>Operatorul default()public T Pop() { m_StackPointer--; if(m_StackPointer &gt;= 0) { return m_Items[m_StackPointer]; } else { m_StackPointer = 0; return default(T); } } //default(T) intoarce valoare default a tipului T</p> <p>Mai multi parametrii//lista cu legaturiclass Node { public K Key; public T Item; public Node NextNode; public Node() { Key = default(K); Item = defualt(T); NextNode = null; } public Node(K key,T item,Node nextNode) { Key = key; Item = item; NextNode = nextNode; } } public class LinkedList { Node m_Head; public LinkedList() { m_Head = new Node(); } public void AddHead(K key,T item) { Node newNode = new Node(key,item,m_Head.NextNode); m_Head.NextNode = newNode; } }</p> <p>Mai multi parametriiFiecare nod contine o cheie (de tip generic K) si o valoare (de tip generic T); Utilizare: LinkedList list1= new LinkedList(); list1.AddHead(123,"AAA");</p> <p>LinkedList list2 = new LinkedList(); list2.AddHead(DateTime.Now,"AAA");</p> <p>Alias pentru combinatii particulare de tipuriusing List = LinkedList; class ListClient { static void Main(string[] args) { List list = new List(); list.AddHead(123,"AAA"); } }</p> <p>//scope: la nivel de fisier in care apare</p> <p>Constrangeri pentru tipurile generice1. Constr. la derivare: parametrul generic este derivat dintr-o superclasa sau interfata public class LinkedList { T Find(K key) {...} //cautarea unei valori dupa cheie public T this[K key] { //indexare dupa cheie get{return Find(key);} } } //nu se compileaza in acest moment</p> <p>T Find(K key) { Node current = m_Head; while(current.NextNode != null) { if(current.Key == key) //nu se compileaza break; else current = current.NextNode; } return current.Item; }</p> <p>public interface IComparable { int CompareTo(object obj);</p> <p>}</p> <p>public class LinkedList where K : IComparable { T Find(K key) { Node current = m_Head; while(current.NextNode != null) { if(current.Key.CompareTo(key) == 0) break; else current = current.NextNode; } return current.Item; } //Restul implementarii }</p> <p>Alte combinatii1. public class MyBaseClass {...} public class LinkedList where K : MyBaseClass {...}</p> <p>2. public class MyClass where T : U {...}</p> <p>3. public interface IMyInterface {...} public class MyClass where T : IMyInterface {...}MyClass obj = new MyClass();</p> <p>Constrangere Constructorclass Node where T : new() { public K Key; public T Item; public Node NextNode; public Node() { Key = default(K); Item = new T(); NextNode = null; } } //tipul T trebuie sa detina constructor default</p> <p>Constrangere tip referinta/valoarepublic class MyClass where T : struct {...} public class MyClass where T : class {...}</p>