System.Type.MakeGenericType-Metod

Anmärkning

Den här artikeln innehåller ytterligare kommentarer till referensdokumentationen för det här API:et.

Med MakeGenericType metoden kan du skriva kod som tilldelar specifika typer till typparametrarna för en allmän typdefinition, vilket skapar ett Type objekt som representerar en viss konstruktionstyp. Du kan använda det här Type objektet för att skapa exemplar av typen som du har konstruerat.

Typer som konstruerats med MakeGenericType kan vara öppna, dvs. vissa av deras typargument kan vara typparametrar för omslutande generiska metoder eller typer. Du kan använda sådana öppna konstruktionstyper när du genererar dynamiska sammansättningar. Tänk till exempel på klasserna Base och Derived i följande kod.

public class Base<T, U> { }
public class Derived<V> : Base<int, V> { }
type Base<'T, 'U>() = class end
type Derived<'V>() = inherit Base<int, 'V>()
Public Class Base(Of T, U)
End Class
Public Class Derived(Of V)
    Inherits Base(Of Integer, V)
End Class

För att generera Derived i en dynamisk sammansättning är det nödvändigt att konstruera dess bastyp. Det gör du genom att anropa MakeGenericType metoden för ett Type objekt som representerar klassen Base, med hjälp av de allmänna typargumenten Int32 och typparametern V från Derived. Eftersom både typer och generiska typparametrar representeras av Type objekt kan en matris som innehåller båda skickas till MakeGenericType metoden.

Anmärkning

En konstruerad typ som Base<int, V> är användbar när du genererar kod, men du kan inte anropa metoden för den MakeGenericType här typen eftersom den inte är en allmän typdefinition. Om du vill skapa en sluten GetGenericTypeDefinition konstruktionstyp som kan instansieras anropar du först metoden för att hämta ett Type objekt som representerar den generiska typdefinitionen och anropar MakeGenericType sedan med önskade typargument.

Objektet Type som returneras av MakeGenericType är detsamma som det Type som erhålls genom att anropa GetType metoden för den resulterande konstruerade typen, eller GetType metoden för någon konstruerad typ som skapades från samma generiska typdefinition med samma typargument.

Anmärkning

En matris med generiska typer är inte i sig en allmän typ. Du kan inte anropa MakeGenericType en matristyp som C<T>[] (Dim ac() As C(Of T) i Visual Basic). Anropa C<T>[] för att hämta den generiska typdefinitionen GetElementType; anropa C<T> på den generiska typdefinitionen för att skapa den konstruerade typen; och anropa slutligen metoden MakeGenericType på den konstruerade typen för att skapa en matristyp. Detsamma gäller för pekartyper och ref typer (ByRef i Visual Basic).

En lista över de invarianta villkoren för termer som används i allmän reflektion finns i egenskapskommentarerna IsGenericType .

Kapslade typer

Om en allmän typ definieras med C#, C++ eller Visual Basic är alla kapslade typer generiska. Detta gäller även om de kapslade typerna inte har några egna typparametrar, eftersom alla tre språken innehåller typparametrarna för omslutande typer i typparameterlistorna för kapslade typer. Tänk på följande klasser:

public class Outermost<T>
{
    public class Inner<U>
    {
        public class Innermost1<V> {}
        public class Innermost2 {}
    }
}
Public Class Outermost(Of T)
    Public Class Inner(Of U)
        Public Class Innermost1(Of V)
        End Class
        Public Class Innermost2
        End Class
    End Class
End Class

Typparameterlistan för den kapslade klassen Inner har två typparametrar och TU, varav den första är typparametern för dess omslutande klass. På samma sätt har typparameterlistan för den kapslade klassen Innermost1 tre typparametrar, T, U, och V, med T och U kommer från dess omslutande klasser. Den kapslade klassen Innermost2 har två typparametrar och TU, som kommer från dess omslutande klasser.

Om parameterlistan för den omslutande typen har fler än en typparameter inkluderas alla typparametrar i ordning i typparameterlistan för den kapslade typen.

Om du vill skapa en generisk typ från den generiska typdefinitionen för en kapslad typ anropar MakeGenericType du metoden med matrisen som bildas genom att sammanfoga typargumentmatriserna för alla omslutande typer, med början med den yttersta generiska typen, och slutar med typargumentmatrisen för den kapslade typen, om den har egna typparametrar. Om du vill skapa en instans av Innermost1anropar MakeGenericType du metoden med en matris som innehåller tre typer, som ska tilldelas till T, U och V. Om du vill skapa en instans av Innermost2anropar MakeGenericType du metoden med en matris som innehåller två typer, som ska tilldelas till T och U.

Språken sprider typparametrarna för omslutande typer på det här sättet så att du kan använda typparametrarna för en omslutande typ för att definiera fält av kapslade typer. Annars skulle typparametrarna inte vara tillgängliga inom definitionerna av de kapslade typerna. Det är möjligt att definiera kapslade typer utan att sprida typparametrarna för omslutande typer, genom att generera kod i dynamiska sammansättningar eller med hjälp av Ilasm.exe (IL Assembler). Överväg följande kod för CIL-monteringen:

.class public Outer<T> {
    .class nested public Inner<U> {
        .class nested public Innermost {
        }
    }
}

I det här exemplet går det inte att definiera ett fält av typen T eller U i klassen Innermost, eftersom dessa typparametrar inte finns i omfånget. Följande assemblerkod definierar kapslade klasser som beter sig som de skulle om de definierades i C++, Visual Basic och C#:

.class public Outer<T> {
    .class nested public Inner<T, U> {
        .class nested public Innermost<T, U, V> {
        }
    }
}

Du kan använda Ildasm.exe (IL Disassembler) för att undersöka kapslade klasser som definierats i högnivåspråken och observera det här namngivningsschemat.