Type.MakeGenericType(Type[]) Methode

Definitie

Vervangt de elementen van een matrix met typen voor de typeparameters van de huidige algemene typedefinitie en retourneert een Type object dat het resulterende samengestelde type vertegenwoordigt.

public:
 abstract Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public:
 virtual Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public abstract Type MakeGenericType(params Type[] typeArguments);
[System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")]
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")]
public virtual Type MakeGenericType(params Type[] typeArguments);
public virtual Type MakeGenericType(params Type[] typeArguments);
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")]
public virtual Type MakeGenericType(params Type[] typeArguments);
abstract member MakeGenericType : Type[] -> Type
[<System.Diagnostics.CodeAnalysis.RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")>]
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")>]
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")>]
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
Public MustOverride Function MakeGenericType (ParamArray typeArguments As Type()) As Type
Public Overridable Function MakeGenericType (ParamArray typeArguments As Type()) As Type

Parameters

typeArguments
Type[]

Een matrix van typen die moeten worden vervangen door de typeparameters van het huidige algemene type.

Retouren

Een Type vertegenwoordiging van het samengestelde type dat wordt gevormd door de elementen van typeArguments de typeparameters van het huidige algemene type te vervangen.

Kenmerken

Uitzonderingen

Het huidige type vertegenwoordigt geen algemene typedefinitie. Dat wil gezegd, IsGenericTypeDefinition retourneert false.

typeArguments is null.

– of –

Elk element van typeArguments is null.

Het aantal elementen in typeArguments is niet hetzelfde als het aantal typeparameters in de huidige algemene typedefinitie.

– of –

Elk element voldoet typeArguments niet aan de beperkingen die zijn opgegeven voor de overeenkomstige typeparameter van het huidige algemene type.

– of –

typeArguments bevat een element dat een aanwijzer (IsPointer retourneert), trueeen type verwijzing (IsByRef retourneert), trueof Void.

De aangeroepen methode wordt niet ondersteund in de basisklasse. Afgeleide klassen moeten een implementatie bieden.

Voorbeelden

In het volgende voorbeeld wordt de MakeGenericType methode gebruikt om een samengesteld type te maken op basis van de algemene typedefinitie voor het Dictionary<TKey,TValue> type. Het samengestelde type vertegenwoordigt een Dictionary<TKey,TValue> van Test objecten met tekenreekssleutels.

using System;
using System.Reflection;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        Console.WriteLine("\r\n--- Create a constructed type from the generic Dictionary type.");

        // Create a type object representing the generic Dictionary 
        // type, by omitting the type arguments (but keeping the 
        // comma that separates them, so the compiler can infer the
        // number of type parameters).      
        Type generic = typeof(Dictionary<,>);
        DisplayTypeInfo(generic);

        // Create an array of types to substitute for the type
        // parameters of Dictionary. The key is of type string, and
        // the type to be contained in the Dictionary is Test.
        Type[] typeArgs = { typeof(string), typeof(Test) };

        // Create a Type object representing the constructed generic
        // type.
        Type constructed = generic.MakeGenericType(typeArgs);
        DisplayTypeInfo(constructed);

        // Compare the type objects obtained above to type objects
        // obtained using typeof() and GetGenericTypeDefinition().
        Console.WriteLine("\r\n--- Compare types obtained by different methods:");

        Type t = typeof(Dictionary<String, Test>);
        Console.WriteLine("\tAre the constructed types equal? {0}", t == constructed);
        Console.WriteLine("\tAre the generic types equal? {0}", 
            t.GetGenericTypeDefinition() == generic);
    }

    private static void DisplayTypeInfo(Type t)
    {
        Console.WriteLine("\r\n{0}", t);

        Console.WriteLine("\tIs this a generic type definition? {0}", 
            t.IsGenericTypeDefinition);

        Console.WriteLine("\tIs it a generic type? {0}", 
            t.IsGenericType);

        Type[] typeArguments = t.GetGenericArguments();
        Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
        foreach (Type tParam in typeArguments)
        {
            Console.WriteLine("\t\t{0}", tParam);
        }
    }
}

/* This example produces the following output:

--- Create a constructed type from the generic Dictionary type.

System.Collections.Generic.Dictionary`2[TKey,TValue]
        Is this a generic type definition? True
        Is it a generic type? True
        List type arguments (2):
                TKey
                TValue

System.Collections.Generic.Dictionary`2[System.String, Test]
        Is this a generic type definition? False
        Is it a generic type? True
        List type arguments (2):
                System.String
                Test

--- Compare types obtained by different methods:
        Are the constructed types equal? True
        Are the generic types equal? True
 */
open System
open System.Collections.Generic

type Test() = class end

let displayTypeInfo (t: Type) =
    printfn $"\r\n{t}"

    printfn $"\tIs this a generic type definition? {t.IsGenericTypeDefinition}" 

    printfn $"\tIs it a generic type? {t.IsGenericType}"

    let typeArguments = t.GetGenericArguments()
    printfn $"\tList type arguments ({typeArguments.Length}):"
    for tParam in typeArguments do
        printfn $"\t\t{tParam}"

printfn "\r\n--- Create a constructed type from the generic Dictionary type."

// Create a type object representing the generic Dictionary 
// type, by calling .GetGenericTypeDefinition().
let generic = typeof<Dictionary<_,_>>.GetGenericTypeDefinition()
displayTypeInfo generic

// Create an array of types to substitute for the type
// parameters of Dictionary. The key is of type string, and
// the type to be contained in the Dictionary is Test.
let typeArgs = [| typeof<string>; typeof<Test> |]

// Create a Type object representing the constructed generic type.
let constructed = generic.MakeGenericType typeArgs
displayTypeInfo constructed

(* This example produces the following output:

--- Create a constructed type from the generic Dictionary type.

System.Collections.Generic.Dictionary`2[TKey,TValue]
        Is this a generic type definition? True
        Is it a generic type? True
        List type arguments (2):
                TKey
                TValue

System.Collections.Generic.Dictionary`2[System.String, Test]
        Is this a generic type definition? False
        Is it a generic type? True
        List type arguments (2):
                System.String
                Test
 *)

Public Class Test
    Public Shared Sub Main2()
        Console.WriteLine(vbCrLf & "--- Create a constructed type from the generic Dictionary type.")

        ' Create a type object representing the generic Dictionary 
        ' type, by omitting the type arguments (but keeping the 
        ' comma that separates them, so the compiler can infer the
        ' number of type parameters).
        Dim generic As Type = GetType(Dictionary(Of ,))
        DisplayTypeInfo(generic)

        ' Create an array of types to substitute for the type
        ' parameters of Dictionary. The key is of type string, and
        ' the type to be contained in the Dictionary is Test.
        Dim typeArgs() As Type = {GetType(String), GetType(Test)}

        ' Create a Type object representing the constructed generic
        ' type.
        Dim constructed As Type = generic.MakeGenericType(typeArgs)
        DisplayTypeInfo(constructed)

        ' Compare the type objects obtained above to type objects
        ' obtained using GetType() and GetGenericTypeDefinition().
        Console.WriteLine(vbCrLf & "--- Compare types obtained by different methods:")

        Dim t As Type = GetType(Dictionary(Of String, Test))
        Console.WriteLine(vbTab & "Are the constructed types equal? " _
            & (t Is constructed))
        Console.WriteLine(vbTab & "Are the generic types equal? " _
            & (t.GetGenericTypeDefinition() Is generic))
    End Sub

    Private Shared Sub DisplayTypeInfo(ByVal t As Type)
        Console.WriteLine(vbCrLf & t.ToString())

        Console.WriteLine(vbTab & "Is this a generic type definition? " _ 
            & t.IsGenericTypeDefinition)

        Console.WriteLine(vbTab & "Is it a generic type? " _ 
            & t.IsGenericType)

        Dim typeArguments() As Type = t.GetGenericArguments()
        Console.WriteLine(vbTab & "List type arguments ({0}):", _
            typeArguments.Length)
        For Each tParam As Type In typeArguments       
            Console.WriteLine(vbTab & vbTab & tParam.ToString())
        Next
    End Sub
End Class

' This example produces the following output:
'
'--- Create a constructed type from the generic Dictionary type.
'
'System.Collections.Generic.Dictionary'2[TKey,TValue]
'        Is this a generic type definition? True
'        Is it a generic type? True
'        List type arguments (2):
'                TKey
'                TValue
'
'System.Collections.Generic.Dictionary`2[System.String,Test]
'        Is this a generic type definition? False
'        Is it a generic type? True
'        List type arguments (2):
'                System.String
'                Test
'
'--- Compare types obtained by different methods:
'        Are the constructed types equal? True
'        Are the generic types equal? True

Opmerkingen

Met MakeGenericType de methode kunt u code schrijven waarmee specifieke typen worden toegewezen aan de typeparameters van een algemene typedefinitie, waardoor u een Type object maakt dat een bepaald samengesteld type vertegenwoordigt. U kunt dit Type object gebruiken om runtime-exemplaren van het samengestelde type te maken.

Typen die zijn samengesteld met MakeGenericType kunnen open zijn, dat wil gezegd, sommige van hun typeargumenten kunnen parameters zijn van het insluiten van algemene methoden of typen. U kunt dergelijke open samengestelde typen gebruiken wanneer u dynamische assemblages uitvoert. Denk bijvoorbeeld aan de klassen Base en Derived in de volgende code.

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

Voor het genereren Derived in een dynamische assembly is het noodzakelijk om het basistype te maken. Hiervoor roept u de MakeGenericType methode aan voor een Type object dat de klasse Basevertegenwoordigt, met behulp van de algemene typeargumenten Int32 en de typeparameter V van Derived. Omdat typen en algemene typeparameters beide worden vertegenwoordigd door Type objecten, kan een matrix met beide worden doorgegeven aan de MakeGenericType methode.

Opmerking

Een samengesteld type, zoals Base<int, V> handig bij het verzenden van code, maar u kunt de MakeGenericType methode voor dit type niet aanroepen omdat het geen algemene typedefinitie is. Als u een gesloten samengesteld type wilt maken dat kan worden geïnstantieerd, roept u eerst de GetGenericTypeDefinition methode aan om een Type object op te halen dat de algemene typedefinitie vertegenwoordigt en roept u vervolgens MakeGenericType aan met de gewenste typeargumenten.

Het Type object dat wordt MakeGenericType geretourneerd door is hetzelfde als het Type object dat is verkregen door de GetType methode van het resulterende samengestelde type aan te roepen, of de GetType methode van elk samengesteld type dat is gemaakt op basis van dezelfde algemene typedefinitie met dezelfde typeargumenten.

Opmerking

Een matrix van algemene typen is zelf geen algemeen type. U kunt MakeGenericType niet aanroepen op een arraytype zoals C<T>[] (Dim ac() As C(Of T) in Visual Basic). Als u een gesloten generiek type wilt maken van C<T>[], roept u GetElementType aan om de generieke typedefinitie C<T> te verkrijgen. Roep MakeGenericType aan op de generieke typedefinitie om het geconstrueerde type te maken; en roep ten slotte de MakeArrayType-methode aan op het geconstrueerde type om het matrixtype te maken. Hetzelfde geldt voor aanwijzertypen en ref -typen (ByRef in Visual Basic).

Zie de opmerkingen van de IsGenericType eigenschap voor een lijst met invariante voorwaarden voor termen die in generieke reflectie worden gebruikt.

Geneste typen

Als een algemeen type is gedefinieerd met C#, C++of Visual Basic, zijn de geneste typen allemaal algemeen. Dit geldt zelfs als de geneste typen geen eigen typeparameters hebben, omdat alle drie de talen de typeparameters bevatten van het insluiten van typen in de typeparameterlijsten van geneste typen. Houd rekening met de volgende klassen:

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

De typeparameterlijst van de geneste klasse Inner heeft twee typeparameters T en U, waarvan de eerste de typeparameter van de bijbehorende klasse is. Op dezelfde manier heeft de typeparameterlijst van de geneste klasse Innermost1 drie typeparameters, T, U, en V, waarbij T en U afkomstig zijn van zijn omliggende klassen. De geneste klasse Innermost2 heeft twee typeparameters en TU, die afkomstig zijn van de ingesloten klassen.

Als de lijst met parameters van het insluittype meer dan één typeparameter heeft, worden alle typeparameters in volgorde opgenomen in de lijst met typeparameters van het geneste type.

Als u een generiek type wilt samenstellen vanuit de generieke typedefinitie voor een genest type, roept u de MakeGenericType-methode aan met de array die is gevormd door het samenvoegen van de typeargumentarrays van alle omsluitende typen, te beginnen met het buitenste generieke type en te eindigen met de typeargumentarray van het geneste type zelf, als het typeparameters voor zichzelf heeft. Als u een instantie van Innermost1wilt maken, roept u de MakeGenericType methode aan met een matrix met drie typen, die moet worden toegewezen aan T, U en V. Als u een instantie van Innermost2wilt maken, roept u de MakeGenericType methode aan met een matrix die twee typen bevat, die moet worden toegewezen aan T en U.

De talen geven de typeparameters van het insluiten van typen op deze manier door, zodat u de typeparameters van een omsluittype kunt gebruiken om velden van geneste typen te definiëren. Anders zouden de typeparameters niet in scope zijn binnen de omschrijvingen van de geneste typen. Het is mogelijk om geneste typen te definiëren zonder de typeparameters van omsluittypen door code in dynamische assembly's te verzenden of door de Ilasm.exe (IL Assemblyer) te gebruiken. Houd rekening met de volgende code voor de CIL-assembly:

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

In dit voorbeeld is het niet mogelijk om een veld van het type T of U in klasse Innermostte definiëren, omdat deze typeparameters niet binnen het bereik vallen. Met de volgende assemblyercode worden geneste klassen gedefinieerd die zich gedragen zoals ze zouden worden gedefinieerd in C++, Visual Basic en C#:

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

U kunt de Ildasm.exe (IL Disassembler) gebruiken om geneste klassen te onderzoeken die zijn gedefinieerd in de talen op hoog niveau en dit naamgevingsschema te observeren.

Van toepassing op

Zie ook