Általánosak a .NET-ben

A generics lehetővé teszi, hogy egy metódust, osztályt, struktúrát vagy felületet az általa alkalmazott pontos adattípushoz szabjon. Például a Hashtable osztály használata helyett, amely lehetővé teszi, hogy a kulcsok és értékek bármilyen típusúak legyenek, használhatja az általános Dictionary<TKey,TValue> osztályt, és megadhatja a kulcshoz és az értékhez engedélyezett típusokat. A generikusok előnyei közé tartozik a kód újrafelhasználhatóságának növelése és a típusbiztonság.

Általános eszközök definiálása és használata

Az általánosak olyan osztályok, struktúrák, interfészek és metódusok, amelyek helyőrzőkkel (típusparaméterekkel) rendelkeznek az általuk tárolt vagy használt típusok egy vagy több típusához. Egy általános gyűjteményosztály egy típusparamétert használhat helyőrzőként az általa tárolt objektumok típusához. A típusparaméterek a mezők típusaiként és a metódusok paramétertípusaként jelennek meg. Az általános metódusok a típusparamétert használhatják a visszatérési érték típusaként vagy az egyik formális paraméter típusaként.

Az alábbi kód egy egyszerű általános osztálydefiníciót mutat be.

public class SimpleGenericClass<T>
{
    public T Field;
}
Public Class SimpleGenericClass(Of T)
    Public Field As T

End Class

Egy általános osztály példányának létrehozásakor meg kell adnia a típusparamétereket helyettesítő tényleges típusokat. Ez létrehoz egy új általános osztályt, más néven egy konfigurálott általános osztályt, ahol a kiválasztott típusok mindenhol lecserélődnek, ahol a típusparaméterek megjelennek. Az eredmény egy típusbiztos osztály, amely az Ön által választott típushoz van igazítva, ahogyan az alábbi kód is mutatja.

public static void Main()
{
    SimpleGenericClass<string> g = new SimpleGenericClass<string>();
    g.Field = "A string";
    //...
    Console.WriteLine($"SimpleGenericClass.Field           = \"{g.Field}\"");
    Console.WriteLine($"SimpleGenericClass.Field.GetType() = {g.Field.GetType().FullName}");
}
Public Shared Sub Main()
    Dim g As New SimpleGenericClass(Of String)
    g.Field = "A string"
    '...
    Console.WriteLine("SimpleGenericClass.Field           = ""{0}""", g.Field)
    Console.WriteLine("SimpleGenericClass.Field.GetType() = {0}", g.Field.GetType().FullName)
End Sub

Terminológia

A .NET-ben a generikus típusokkal kapcsolatban a következő kifejezéseket használjuk:

  • Az általános típusdefiníciós egy sablonként működő osztály-, struktúra- vagy felületdeklaráció, amely helyőrzőkkel rendelkezik a benne található vagy használható típusokhoz. A System.Collections.Generic.Dictionary<TKey,TValue> osztály például két típust tartalmazhat: kulcsokat és értékeket. Mivel az általános típusdefiníció csak sablon, nem hozhat létre általános típusdefiníciót tartalmazó osztály- vagy struktúra- vagy felületpéldányokat.

  • általános típusparaméterekvagy típusparaméterek az általános típus- vagy metódusdefiníció helyőrzői. Az System.Collections.Generic.Dictionary<TKey,TValue> általános típus két típusparamétert tartalmaz, TKey és TValue, amelyek a kulcsok és értékek típusait jelölik.

  • A létrehozott általános típusú , vagy a létrehozott típus, az eredménye annak, hogy típusokat adunk meg egy általános típusalapú definíció általános típusparamétereinek.

  • A általános típusargumentum minden olyan típus, amely egy általános típusparamétert helyettesít.

  • Az általános általános kifejezés a létrehozott típusokat és az általános típusdefiníciókat egyaránt tartalmazza.

  • Kovariancia és a generikus típusú paraméterek lehetővé teszik olyan generikus típusok használatát, amelyek típusargumentumai származtatottabbak (kovariancia) vagy kevésbé származtatottak (kontravariancia), mint a célként létrehozott típus. A kovariancia és az ellenvariancia együttes elnevezése variancia. További információ: Kovariancia és kontravariancia.

  • korlátozások az általános típusparaméterekre vonatkozó korlátok. Előfordulhat például, hogy egy típusparamétert olyan típusokra korlátoz, amelyek implementálják az System.Collections.Generic.IComparer<T> általános felületet, így biztosítható, hogy a típus példányai rendezhetők legyenek. A típusparamétereket olyan típusokra is korlátozhatja, amelyek egy adott alaposztálysal rendelkeznek, paraméter nélküli konstruktorsal rendelkeznek, vagy referencia- vagy értéktípusok. Az általános típusú felhasználók nem helyettesíthetik azokat a típusargumentumokat, amelyek nem felelnek meg a korlátozásoknak.

  • Az általános metódusdefiníciós egy olyan metódus, amely két paraméterlistával rendelkezik: az általános típusparaméterek listája és a formális paraméterek listája. A típusparaméterek megjelenhetnek visszatérési típusként vagy a formális paraméterek típusaiként, ahogyan az alábbi kód is mutatja.

    T MyGenericMethod<T>(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
    
    Function MyGenericMethod(Of T)(ByVal arg As T) As T
        Dim temp As T = arg
        '...
        Return temp
    End Function
    

    Az általános metódusok általános vagy nemgenerikus típusok esetén is megjelenhetnek. Fontos megjegyezni, hogy egy metódus nem csak azért általános, mert egy általános típushoz tartozik, vagy azért, mert olyan formális paraméterekkel rendelkezik, amelyek típusai a beágyazási típus általános paraméterei. A metódus csak akkor általános, ha saját típusparaméter-listával rendelkezik. Az alábbi kódban csak a G metódus általános.

    class A
    {
        T G<T>(T arg)
        {
            T temp = arg;
            //...
            return temp;
        }
    }
    class MyGenericClass<T>
    {
        T M(T arg)
        {
            T temp = arg;
            //...
            return temp;
        }
    }
    
    Class A
        Function G(Of T)(ByVal arg As T) As T
            Dim temp As T = arg
            '...
            Return temp
        End Function
    End Class
    Class MyGenericClass(Of T)
        Function M(ByVal arg As T) As T
            Dim temp As T = arg
            '...
            Return temp
        End Function
    End Class
    

A generikusok előnyei és hátrányai

Az általános gyűjtemények és meghatalmazottak használatának számos előnye van:

  • Típusbiztonság. A generics áttolja a típusbiztonság terheit a fordítóra. Nincs szükség kód írására a megfelelő adattípus teszteléséhez, mert a fordítás időpontjában kerül érvényesítésre. Csökken a típus-öntés szükségessége és a futásidejű hibák lehetősége.

  • Kevesebb kód van, és a kód könnyebben újra felhasználható. Nem kell alaptípusból származtatni és felülbírálni a tagokat. A LinkedList<T> például készen áll az azonnali használatra. Létrehozhat például egy csatolt sztringlistát a következő változódeklarációval:

    LinkedList<string> llist = new LinkedList<string>();
    
    Dim llist As New LinkedList(Of String)()
    
  • Jobb teljesítmény. Az általános gyűjteménytípusok általában jobban teljesítenek az értéktípusok tárolására és manipulálására, mert nincs szükség az értéktípusok becsomagolására.

  • Az általános meghatalmazottak anélkül engedélyezik a típusbiztos visszahívásokat, hogy több delegáltosztályt kellene létrehozniuk. Az általános Predicate<T> delegált például lehetővé teszi egy olyan metódus létrehozását, amely implementálja a saját keresési feltételeket egy adott típushoz, és a metódust az Array típusú metódusokkal( például Find, FindLastés FindAll) használhatja.

  • A generics leegyszerűsíti a dinamikusan létrehozott kódot. Ha dinamikusan generált kóddal rendelkező általános kódot használ, nem kell létrehoznia a típust. Ez növeli azoknak a forgatókönyveknek a számát, amelyekben egyszerűsített dinamikus metódusokat használhat teljes szerelvények létrehozása helyett. További információ: Dinamikus módszerek definiálása és végrehajtása és DynamicMethod.

Az alábbiakban néhány általános korlátozást ismertetünk:

  • Az általános típusok a legtöbb alaposztályból származhatnak, például MarshalByRefObject (és kényszerekkel megkövetelhető, hogy az általános típusparaméterek az alaposztályokból, például a MarshalByRefObject) származtathatók. A .NET azonban nem támogatja a környezethez kötött általános típusokat. Az általános típus származtatható ContextBoundObject-ból, de ennek a típusnak a példányosítása TypeLoadException-et okoz.

  • Az enumerálások nem rendelkeznek általános típusparaméterekkel. Az enumerálás csak véletlenül lehet általános (például azért, mert a Visual Basic, C# vagy C++ használatával definiált általános típusba van beágyazva). További információkért lásd az "Enumerációk" részt a Közös típusú rendszer.

  • Az egyszerűsített dinamikus metódusok nem lehetnek általánosak.

  • A Visual Basic, a C# és a C++ alkalmazásban az általános típusba zárt beágyazott típus csak akkor hozható létre, ha az összes beágyazási típus típusparamétereihez típusok vannak rendelve. Ennek másik módja, hogy a tükrözésben az ilyen nyelvekkel definiált beágyazott típus tartalmazza az összes beágyazási típus típusparamétereit. Ez lehetővé teszi, hogy a beágyazott típus tagdefinícióiban a beágyazási típusok típusparaméterei használhatók legyenek. A további információkért lásd a "Beágyazott típusok" címet a MakeGenericType-ban.

    Megjegyzés

    A kód dinamikus szerelvényben vagy a Ilasm.exe (IL-összeszerelő) használatával történő kibocsátásával definiált beágyazott típusnak nem kell tartalmaznia a beágyazott típusok típusparamétereit; ha azonban nem tartalmazza őket, a típusparaméterek nem tartoznak a beágyazott osztály hatókörébe.

    A további információkért lásd a "Beágyazott típusok" címet a MakeGenericType-ban.

Osztálytár és nyelvi támogatás

A .NET számos általános gyűjteményosztályt biztosít a következő névterekben:

A rendezés és egyenlőség összehasonlításának általános felületeit a System névtérben, valamint az eseménykezelők, konverziók és keresési predikátumok általános delegálási típusai biztosítják.

A System.Numerics névtér általános interfészeket biztosít a matematikai funkciókhoz (.NET 7 és újabb verziókban érhető el). További információ: Általános matematika.

Az általános típusok és metódusok vizsgálatának támogatása hozzá lett adva a System.Reflection névtérhez, a generikus típusokat és metódusokat tartalmazó dinamikus szerelvények kibocsátásához a System.Reflection.Emit-hez, valamint a generikus elemeket tartalmazó forrásdiagramok létrehozásához a System.CodeDom-höz.

A közös nyelvi futtatókörnyezet új opkódokat és előtagokat biztosít a közös köztes nyelv (CIL) általános típusainak támogatásához, beleértve a Stelem, Ldelem, Unbox_Any, Constrainedés Readonly.

A Visual C++, C# és Visual Basic mind teljes körű támogatást nyújtanak az általános elemek definiálására és használatára. További információ a nyelvi támogatásról: Általános típusok a Visual Basic-ban, Az általánosbemutatása és A Visual C++általános típusainak áttekintése.

Beágyazott típusok és általános típusok

Az általános típusba ágyazott típus a beágyazott általános típus típusparamétereitől függhet. A közös nyelvi futtatókörnyezet a beágyazott típusokat általánosnak tekinti, még akkor is, ha nem rendelkeznek saját általános típusparaméterekkel. Beágyazott típusú példány létrehozásakor meg kell adnia az összes ide tartozó általános típus típusargumentumait.

Cím Leírás
Általános gyűjtemények a .NET keretrendszerben A .NET általános gyűjteményosztályai és egyéb általános típusait ismerteti.
Tömbök és listák manipulálására szolgáló általános meghatalmazottak A tömb vagy gyűjtemény elemein végrehajtandó konverziók, keresési predikátumok és műveletek általános delegáltjait ismerteti.
Általános matematikai Ismerteti, hogyan hajthat végre általános matematikai műveleteket.
Általános interfészek Az általános felületeket ismerteti, amelyek általános típusok családjainak általános funkcióit biztosítják.
Kovariancia és kontravariancia A kovariancia és a kontravariancia általános típusparaméterekben való leírását ismerteti.
Gyakran használt gyűjteménytípusok Összefoglalja a .NET gyűjteménytípusainak jellemzőit és használati forgatókönyveit, beleértve az általános típusokat is.
Mikor érdemes használni az általános gyűjteményeket Általános gyűjteménytípusok használatának általános szabályait ismerteti.
Útmutató: Általános típus definiálása a Reflection Emit segítségével Ismerteti, hogyan hozhat létre olyan dinamikus szerelvényeket, amelyek általános típusokat és metódusokat tartalmaznak.
Általános típusok a Visual Basic Ismerteti a Visual Basic-felhasználók általános funkcióit, beleértve az általános típusok használatára és meghatározására vonatkozó útmutatókat.
Bevezetés a Generics használatába Áttekintést nyújt a C#-felhasználók általános típusainak meghatározásáról és használatáról.
Generikusok áttekintése a Visual C++-ban Ismerteti a C++ felhasználók általános funkcióit, beleértve az általános és a sablonok közötti különbségeket.

Referenciák