Načo je to dobre?
- Odstráni sa tým nepríjemné boxovanie/odboxovanie a pretypovávanie.
- Silná kontrola typov bude prebiehať už pri kompilácii.
- Možnosť nastaviť obmedzenia na typové parametre.
- Znovu použitie kódu.
Príklad:
public class Stack<T> { T[] items; int count; public void Push(T item) {...} public T Pop() {...} }
Označenie veľke T nazývame typový parameter a je špecifikovaný v lomených zátvorkách za menom definovaného objektu (<T>). Tento názov sa používa ako zástupný symbol pre skutočný dátovy typ. Písmeno T sa používa len z dohody, môžete tam dať ľubovoľné písmeno. Lenže od čias CPP a šablón si programátori zvykli na T .
Generické typy môžu mať viac než jeden parametrický typ.
Príklad :
public class Image<TColor, TDepth> { ... }
Príklad :
using System; namespace Test { class TestClass { public static void Swap<T>(ref T input1,ref T input2) { T temp; temp = input1; input1 = input2; input2 = temp; } } class MainClass { public static void Main (string[] args) { int a=10,b=2; TestClass.Swap<int>(ref a,ref b); Console.WriteLine ("a={0} ; b={1}",a,b); Console.ReadKey(); } } }
Output: a=2 ; b=10
Zápis:
int a=10,b=2; TestClass.Swap(ref a,ref b); //OK TestClass.Swap<int>(ref a,ref b); //OK TestClass.Swap<double>(ref a,ref b); //Error - a,b musia byt double
// Error CS1502: The best overloaded method match for `Test.TestClass.Swap<double>(ref double, ref double)' has some invalid arguments (CS1502) (Test)
Obmedzenia pre typový parameter
C# poskytuje tzv obmedzenia, ktoré môžeme aplikovať na generics . Každý obmedzený typový parameter má oddeľovač where.
/// <summary> /// Typovy parameter musi mat implementovany interface IEnumerable. /// </summary> class Class1<T> where T : IDisposable { } /// <summary> /// Typovy parameter musi byt struct. /// </summary> class Class2<T> where T : struct { } /// <summary> /// Typovy parameter musi byt trieda s verejnym bezparam. konstruktorom /// </summary> class Class3<V> where V : class, new() { }
public class Image<TColor, TDepth> : CvArray<TDepth>, IImage, IDisposable, ICloneable, IEquatable<Image<TColor, TDepth>> where TColor : struct, new(), IColor where TDepth : new()
Vytvorenie generic metódy :
V niektorých prípadoch nie je typový parameter potrebný pre celú triedu, ale iba vo vnútri konkrétnej metódy.
public void MyGenericMethod<T> (T x, T y) where T : struct {. . .}
Vytvorenie generic Interface :
public interface IMyGenericInterfce<T> { void Method1(T a, T b); T Method2(T a, T b); } //Pouzitie interface: public class MyClass : IMyGenericInterfce<int> { public void Method1(int a, int b) {. . .} public int Method2(int a, int b) {. . .} }
Vytvorenie generic Delegáta :
public delegate void MyGenericDelegate<T>(T a, T b); //Pouzitie MyGenericDelegate<int> myDel1 = new MyGenericDelegate<int>(MyTargetMethod1); myDel1(5, 10); MyGenericDelegate<string> myDel2 = new MyGenericDelegate<string>(MyTargetMethod2); myDel2("a", "b"); public static void MyTargetMethod1(int x, int y) {. . .} public static void MyTargetMethod2(string x, string y) {. . .}