Wprowadzenie do C # Generics
Więc jaka jest koncepcja Generics w C #? Krótko mówiąc, jest to koncepcja definiowania klas niezależnych od typu, interfejsów, metod, delegatów, właściwości itp. Oznacza to, że można zdefiniować ogólną treść klasy lub metody i podać rzeczywisty typ podczas wywołania.
Tak więc, generyczne są jak szablony kodu. Pozwalają napisać bezpieczny blok kodu bez odwoływania się do konkretnego typu danych. Typ kodu jest określany podczas kompilacji podczas wywołania wywołania dla Twojej klasy lub metody.
Składnia ogólnych w C #
Spójrzmy na składnię deklaracji ogólnej w C #. Jest to bardzo prosta składnia.
Jako powszechna praktyka litera „T”, wielka i zamknięta w nawiasach kątowych, oznacza deklarację kodu ogólnego w C #. Ale to nie jest mandat. Każda litera wielka, zawarta w nawiasach kątowych, może być użyta do oznaczenia kodu ogólnego.
Deklaracja klasy ogólnej:
public class MyGenericClass
Tworzenie wystąpienia klasy ogólnej:
MyGenericClass = new MyGenericClass();
Deklarowanie ogólnej klasy pochodnej:
public class MyGenericDerivedClass : MyGenericBaseClass
Deklaracja ogólnej metody:
public T MyGenericMethod(T item);
Jak działają generyczne w C #?
Kiedy deklarujesz kod ogólny w C #, kompilator tworzy szablon równoważny z tym kodem. Ten szablon jest sprawdzany pod kątem wszystkich błędów kompilacji oprócz bezpieczeństwa typu. Kolejny krok następuje, gdy kod ogólny zostanie wywołany lub wywołany w innej części programu. W momencie wywołania określasz typ, z którym skompilowany zostanie kod ogólny. Gdy kompilator osiągnie punkt wywołania, wstawia typ określony we wcześniej skompilowanym szablonie. Jest to następnie ponownie kompilowane w celu sprawdzenia bezpieczeństwa typu. Po przekazaniu kod jest gotowy do wykonania.
Widzimy skompilowany kod w poniższych przykładach, aby lepiej zrozumieć ogólne szablony.
Przykład ogólnych w C #
Poniżej znajdują się różne przykłady C # Generics:
Generyczne z klasą
Kod:
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();
))
Wynik:
Ten sam kod można również przepisać jak poniżej. To ilustruje siłę definiowania ogólnej klasy, która może być bezpieczna dla wielu typów w jednym obiekcie.
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();
)
)
Wynik:
Skompilowany kod:
Aby uzyskać perspektywę rozwiązania typu danych w Generics, spójrzmy na skompilowany kod wygenerowany podczas tworzenia instancji klasy z liczbami całkowitymi i ciągami znaków w powyższym przykładzie.
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();
)
)
Generics with Method
Kod:
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;
)
)
Wynik:
Przestrzeń nazw System.Collections.Generic
Przestrzeń nazw System.Collections.Generic w języku C # zawiera interfejsy i klasy definiujące kolekcje ogólne. Pozwalają programistom tworzyć kolekcje ogólne, które są lepsze pod względem wydajności i tak silnie typowe jak kolekcje inne niż ogólne.
Ta przestrzeń nazw zawiera listy, słowniki, listy połączone, skróty, pary klucz-wartość, stosy itp., Z których wszystkie mają charakter ogólny. Programiści mogą je zaimplementować w swoim kodzie.
Znaczenie generycznych C #
Poniżej znajduje się znaczenie C # Generics w następujący sposób:
- Generics Allow Code-Wielokrotnego użytku: podstawowa zasada dobrego programowania. Nie musisz pisać tego samego kodu dla każdego oczekiwanego typu danych. Wystarczy zdefiniować kod niezależny od typu i poinformować kompilator, że rzeczywisty typ danych zostanie podany w momencie wywołania kodu.
- Zapobiegaj kosztom boksowania i rozpakowywania: Oczywiście użycie ogólnych może być ominięte przez klasę obiektów. Poniższe dwa fragmenty kodu są równoważne w swoich zadaniach.
Kod ogólny: public T MyFunc (element T);
Kod nieogólny : obiekt publiczny MyFunc (element obiektu)
Klasa obiektowa zastępuje wszystkie klasy, a zatem powyższy niepochodzący z kodu kod można również wykorzystać do wygenerowania szablonów kodu niezależnych od typu.
Istnieje jednak ogromna różnica w wydajności między tymi dwoma kodami. Korzystanie z klasy obiektu pociąga za sobą dodatkowy koszt boksowania i rozpakowywania typów danych. Leki generyczne eliminują to, a zatem mają lepszą wydajność.
Wniosek
W ten sposób widzieliśmy, w jaki sposób leki generyczne są niezbędną funkcją programowania. Jest to bardzo przydatna koncepcja, nie tylko w języku C #, ale w większości nowoczesnych języków programowania.
Ponadto zdecydowanie zaleca się poznanie System.Collections.Generic przestrzeni nazw w C #. Ponadto, aby zrozumieć działanie leków ogólnych, zapoznaj się ze sposobem, w jaki boks i rozpakowywanie mają wpływ na pamięć oraz czas wykonywania.
Polecane artykuły
To jest przewodnik po C # Generics. Tutaj omawiamy znaczenie i sposób działania generics w C # wraz z różnymi przykładami i implementacją kodu. Możesz także przejrzeć nasze inne sugerowane artykuły, aby dowiedzieć się więcej -
- Bezpośrednie porównanie C # lub operatora
- Przeciążanie i zastępowanie w Javie
- Jakie jest zastosowanie metody przeciążania?
- Jak działa Sealed Class w C #?
- Typy i obsługa błędów w JavaScript
- Kolekcje PL / SQL | Składnia, typy, wyjątki