Úvod do C # Generics
Jaký je tedy pojem Generics v C #? Jednoduše řečeno, jedná se o koncept definování tříd, rozhraní, metod, delegátů, vlastností atd. Nezávislých na typu. To znamená, že můžete definovat obecnou třídu nebo tělo metody a poskytnout skutečný typ během vyvolání.
Generics jsou tedy jako kódové šablony. Umožňují napsat kódový blok bezpečný pro daný typ, aniž by odkazovali na konkrétní typ dat. Typ kódu je určen při kompilaci během vyvolávacího volání pro vaši třídu nebo metodu.
Syntaxe generik v C #
Podívejme se na syntax generické deklarace v C #. Je to velmi jednoduchá syntaxe.
Jako běžná praxe označuje písmeno „T“ v hlavním městě a uzavřené v hranatých závorkách prohlášení o generickém kódu v C #. To však není mandát. K označení generického kódu lze použít jakékoli velké písmeno uzavřené v hranatých závorkách.
Prohlášení obecné třídy:
public class MyGenericClass
Okamžitá generická třída:
MyGenericClass = new MyGenericClass();
Prohlášení obecné odvozené třídy:
public class MyGenericDerivedClass : MyGenericBaseClass
Deklarace obecné metody:
public T MyGenericMethod(T item);
Jak generici pracují v C #?
Když deklarujete obecný kód v C #, kompilátor vytvoří šablonu ekvivalentní tomuto kódu. V této šabloně se kontrolují všechny chyby kompilace s výjimkou typu zabezpečení. Další krok nastane, když je generický kód vyvolán nebo vyvolán v jiné části programu. V okamžiku vyvolání určíte typ, s nímž bude generický kód kompilován. Když kompilátor dosáhne vyvolávacího bodu, vloží typ určený v dříve kompilované šabloně. To se pak znovu překompiluje, aby se zkontrolovala bezpečnost typu. Po předání je kód připraven k provedení.
Kompilovaný kód bychom viděli v příkladech níže, abychom lépe porozuměli obecným šablonám.
Příklad generik v C #
Níže jsou uvedeny různé příklady C # Generics:
Generika s třídou
Kód:
using System;
using System.Collections.Generic;
public class GenericClass
(
List genericList;
public GenericClass()
(
genericList = new List();
)
public void AddToList(T item)
(
genericList.Add(item);
)
public void DisplayList()
(
foreach (var ele in genericList)
(
Console.Write("(0)\t", ele);
)
)
)
public class Program
(
public static void Main()
(
GenericClass intGenericObj = new GenericClass();
GenericClass stringGenericObj = new GenericClass();
intGenericObj.AddToList(28);
intGenericObj.AddToList(999);
intGenericObj.AddToList(0);
intGenericObj.AddToList(-123);
intGenericObj.AddToList(100);
stringGenericObj.AddToList("Hello");
stringGenericObj.AddToList("Bonjour");
stringGenericObj.AddToList("Ola");
stringGenericObj.AddToList("Ciao");
stringGenericObj.AddToList("Hallo");
intGenericObj.DisplayList();
Console.WriteLine("\n");
stringGenericObj.DisplayList();
))
Výstup:
Stejný kód lze také přepsat níže. To ilustruje schopnost definovat obecnou třídu, která může být pro jeden typ bezpečná pro více typů.
using System;
using System.Collections.Generic;
public class GenericClass
(
List genericList1;
List genericList2;
public GenericClass()
(
genericList1 = new List();
genericList2 = new List();
)
public void AddToList(T item1, U item2)
(
genericList1.Add(item1);
genericList2.Add(item2);
)
public void DisplayList()
(
foreach (var ele in this.genericList1)
(
Console.Write("(0)\t", ele);
)
Console.WriteLine("\n");
foreach (var ele in this.genericList2)
(
Console.Write("(0)\t", ele);
)
)
)
public class Program
(
public static void Main()
(
GenericClass genericObj = new GenericClass();
genericObj.AddToList(28, "Hello");
genericObj.AddToList(999, "Bonjour");
genericObj.AddToList(0, "Ola");
genericObj.AddToList(-123, "Ciao");
genericObj.AddToList(100, "Hallo");
genericObj.DisplayList();
)
)
Výstup:
Zkompilovaný kód:
Chcete-li získat představu o tom, jak je typ dat vyřešen v Generics, pojďme se podívat na kompilovaný kód vygenerovaný, když vytvoříme instanci třídy s typy integer a string ve výše uvedeném příkladu.
using System;
using System.Collections.Generic;
public class GenericClass
(
List genericList1;
List genericList2;
public GenericClass()
(
genericList1 = new List();
genericList2 = new List();
)
public void AddToList(int item1, string item2)
(
genericList1.Add(item1);
genericList2.Add(item2);
)
public void DisplayList()
(
foreach (var ele in this.genericList1)
(
Console.Write("(0)\t", ele);
)
Console.WriteLine("\n");
foreach (var ele in this.genericList2)
(
Console.Write("(0)\t", ele);
)
)
)
public class Program
(
public static void Main()
(
GenericClass genericObj = new GenericClass();
genericObj.AddToList(28, "Hello");
genericObj.AddToList(999, "Bonjour");
genericObj.AddToList(0, "Ola");
genericObj.AddToList(-123, "Ciao");
genericObj.AddToList(100, "Hallo");
genericObj.DisplayList();
)
)
Obecná metoda
Kód:
using System;
using System.Collections.Generic;
public class Program
(
public static void Main()
(
int() intArr = (12, 23, 43, 94, 35);
double() doubleArr = (12.3, 45.6, 98.7, 1.45, 82.653);
string() strArr = ("Hello", "Bonjour", "Ola", "Ciao", "Hallo");
Console.WriteLine("The largest integer in the array is (0)", findMax(intArr));
Console.WriteLine("The largest floating-point number in the array is (0)", findMax(doubleArr));
Console.WriteLine("The largest string in the array is (0)", findMax(strArr));
)
static T findMax(T() items)
where T : IComparable
(
T max = items(0);
int position = 0;
for (int i = 1; i < items.Length; i++)
(
if (items(i).CompareTo(max) > 0)
(
max = items(i);
position = i;
)
)
return max;
)
)
Výstup:
System.Collections.Generic namespace
Obor názvů System.Collections.Generic v C # obsahuje rozhraní a třídy definující obecné kolekce. Umožňují programátorům vytvářet obecné kolekce, které mají lepší výkon a jsou stejně silné jako ne-obecné kolekce.
Tento obor názvů obsahuje seznamy, slovníky, propojené seznamy, hashovací páry, páry klíč-hodnota, hromádky atd., Které jsou všechny generické povahy. Programátoři je mohou implementovat do svého kódu.
Význam C # generik
Níže je uveden význam C # generiků:
- Generici umožňují opakovanou použitelnost kódu: základní princip dobrého programování. Nemusíte psát stejný kód pro každý očekávaný typ dat. Jednoduše definujete kód nezávislý na typu a řeknete kompilátoru, že skutečný datový typ bude poskytnut v okamžiku vyvolání kódu.
- Zabraňte nákladům na box a unboxing: Samozřejmě lze použití generik obejít prostřednictvím třídy objektů. Níže uvedené dva kusy kódu jsou ve svých úkolech rovnocenné.
Obecný kód: veřejné T MyFunc (položka T);
Non-Generic Code: public object MyFunc (položka objektu)
Třída objektu nahrazuje všechny třídy, a výše uvedený ne-generický kód lze tedy také použít k vygenerování typově nezávislých kódových šablon.
Mezi těmito dvěma kódy je však velká mezera ve výkonu. Používání třídy objektů přináší další náklady na box a rozbalení typů dat. Generici to eliminují a mají tak lepší výkon.
Závěr
Viděli jsme tedy, jak jsou generici povinnou součástí programování. Toto je velmi užitečný koncept, a to nejen v C #, ale ve většině moderních programovacích jazyků.
Dále se důrazně doporučuje seznámit se s System.Collections.Generic namespace v C #. Abychom pochopili výkon generik, důkladně se ponořte o tom, jak box a unboxing mají vliv na paměť a dobu provedení.
Doporučené články
Toto je průvodce C # Generics. Zde diskutujeme význam a způsob práce generiků v jazyce C # spolu s různými příklady a implementací kódu. Další informace naleznete také v dalších navrhovaných článcích -
- Porovnání typu C # nebo Operator
- Přetížení a přetečení v Javě
- Co je to přetížení metody?
- Jak funguje Sealed Class v C #?
- Typy a manipulace s chybami v JavaScriptu
- Kolekce PL / SQL | Syntaxe, typy, výjimky