C # je silně psaný jazyk. To znamená, že při použití C # byste měli deklarovat typ před uložením dat v něm. Ačkoli tento typ bezpečnosti pomáhá vynucovat bezpečnost a interoperabilitu mezi jazyky, které cílí na spravované prostředí, jste jako vývojář omezeni na definování typu jakéhokoli objektu, se kterým potřebujete pracovat.
Dobře, ale co když chcete ukládat data do typicky bezpečné kolekce bez jakýchkoli režijních nákladů na rozbalování a rozbalování? Tady přicházejí na pomoc generika.
Generika vám umožní pracovat s bezpečnými daty bez režijních nákladů na box a unboxing. Generiky můžete využít k vytvoření typicky bezpečných kolekcí, stejně jako tříd a metod, které mohou typ přijmout jako parametr. Jednou deklarované třídy mohou fungovat s jakýmkoli typem. To pomáhá vašemu kódu být mnohem lépe spravovatelný, rozšiřitelný, udržovatelný a efektivní. V tomto článku bychom prozkoumali generika a jak je lze implementovat pomocí programovacího jazyka C #.
Generika vám pomůže implementovat algoritmy, které mohou pracovat na nejrůznějších typech. Jako příklad možná budete chtít napsat algoritmus pro řazení řady celých nebo dvojitých čísel nebo dokonce řady řetězců. Chcete-li implementovat takové třídicí algoritmy bez generik, obvykle byste potřebovali více metod řazení - jednu pro každý typ.
Jakmile deklarujete třídu nebo metodu pomocí parametrů typu, můžete odložit určení typu, se kterým by třídy nebo metody pracovaly, do doby, než budou tyto třídy a metody přístupné z kódu klienta. Generics podporuje bezpečnost typů, údržbu kódu, účinnost kódu a vylepšený výkon. Všimněte si, že můžete využít generika k implementaci vlastních obecných tříd, rozhraní, metod, událostí a delegátů.
Při použití generik již nemusíte psát cast objekty na příslušné typy - informace o typu jsou dobře zdokumentovány ve vašem kódu. Když používáte generiku, kompilátor provede kontrolu času kompilace vašeho kódu, aby vyhovoval bezpečnosti typu. Kód, který využívá obecné informace, je vždy způsoben vyhýbáním se režii boxu a unboxingu.
Následující výpis kódu ukazuje tři metody, které seřadí vstupní data - pro každý typ potřebujete jednu metodu řazení.
public static int [] Seřadit (int [] integerArray)
{
// Kód pro třídění řady celých čísel
návratové celé číslo;
}
veřejný statický řetězec [] Seřadit (řetězec [] stringArray)
{
// Kód pro třídění řady řetězců
návrat stringArray;
}
public double [] Seřadit (double [] doubleArray)
{
// Kód pro třídění řady čtyřhry
návrat doubleArray;
}
Pokud používáte Generics, můžete mít pouze jednu metodu, která může přijmout parametr typu a na požádání třídit vstupní data.
veřejný třídní algoritmus
{
veřejné statické T [] řazení (T [] inputArray)
{
// Kód pro řazení obecného pole
návrat inputArray;
}
}
Zadejte omezení parametrů
Při práci s generikami byste si měli být vědomi obecných omezení, která zahrnují: derivační omezení a výchozí omezení konstruktoru. Omezení odvození se používají k určení rozhraní nebo třídy, která by se použila k definování derivace pro obecný typ.
Zde je příklad, který ilustruje, jak rozhraní ILogger
byl použit k omezení parametru typu T (při definování DBLogger
třídy) být typu ILogger
rozhraní.
veřejné rozhraní ILogger
{
// Nějaký kód
}
veřejná třída DBLogger, kde T: ILogger
{
// Nějaký kód
}
Parametry obecného typu mohou být buď hodnotového, nebo referenčního typu. Jako příklad můžete definovat svou třídu, která obsahuje parametr obecného typu, některým z následujících způsobů.
veřejná třída FileLogger, kde T: třída
{
// Nějaký kód
}
veřejná třída BaseLogger, kde T: int
{
// Nějaký kód
}
Omezení konstruktoru se používá k vynucení výchozího konstruktoru pro parametr obecného typu. Zde je příklad pro ilustraci tohoto konceptu.
třída DBLogger kde T: new () // Parametr obecného typu T musí mít výchozí konstruktor
{
// Nějaký kód
}
Při práci s dědičností můžete také použít parametry obecného typu. Zde je příklad, který ukazuje, jak toho můžete dosáhnout. Všimněte si, že parametr obecného typu v příkladu uvedeném dále by měl mít výchozí konstruktor.
veřejná třída BaseLogger
{
// Nějaký kód
}
veřejná třída FileLogger: BaseLogger, kde T: new ()
{
// Nějaký kód
}
Následující výpis kódu ukazuje, jak lze implementovat obecné metody.
veřejná třída BaseLogger
{
public void Initialize (T t)
{
// Kód pro inicializaci záznamníku
}
}
Viz výše uvedený fragment kódu. Všimněte si, jak byl parametr obecného typu použit jako parametr v Inicializovat ()
metoda. Ve svých budoucích příspěvcích bych zde diskutoval více o generikách. Další informace o generikách se dozvíte zde: //msdn.microsoft.com/en-us/library/512aeb7t.aspx