Type.MakeGenericType(Type[]) Metódus
Definíció
Fontos
Egyes információk olyan, kiadás előtti termékekre vonatkoznak, amelyek a kiadásig még jelentősen módosulhatnak. A Microsoft nem vállal kifejezett vagy törvényi garanciát az itt megjelenő információért.
Egy típustömb elemeit helyettesíti az aktuális általános típusdefiníció típusparamétereihez, és visszaad egy Type objektumot, amely az eredményül kapott létrehozott típust képviseli.
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
Paraméterek
- typeArguments
- Type[]
Az aktuális általános típus típusparaméterei helyett helyettesítendő típusok tömbje.
Válaszok
Az Type aktuális általános típus típusparamétereinek typeArguments elemeinek helyettesítésével létrehozott létrehozott típust jelképező típus.
- Attribútumok
Kivételek
Az aktuális típus nem általános típusdefiníciót jelöl. Vagyis IsGenericTypeDefinition visszaadja false.
A benne lévő typeArguments elemek száma nem azonos az aktuális általános típusdefiníció típusparamétereinek számával.
-vagy-
Bármely elem typeArguments nem felel meg az aktuális általános típus megfelelő típusparaméteréhez megadott korlátozásoknak.
-vagy-
typeArguments olyan elemet tartalmaz, amely egy mutatótípus (IsPointer visszatérés true), egy bájttípus (IsByRef visszatérés true) vagy Void.
A meghívott metódus nem támogatott az alaposztályban. A származtatott osztályoknak implementációt kell biztosítaniuk.
Példák
Az alábbi példa a MakeGenericType metódus használatával hoz létre egy létrehozott típust a típus általános típusdefiníciójából Dictionary<TKey,TValue> . A létrehozott típus sztringkulcsokkal rendelkező objektumok egy Dictionary<TKey,TValue> részét Test jelöli.
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
Megjegyzések
A MakeGenericType metódus lehetővé teszi olyan kód írását, amely meghatározott típusokat rendel egy általános típusdefiníció típusparamétereihez, így létrehoz egy Type objektumot, amely egy adott létrehozott típust jelöl. Ezzel az Type objektummal létrehozhat futásidejű példányokat a létrehozott típushoz.
A felépített MakeGenericType típusok lehetnek nyitottak, vagyis egyes típusargumentumaik lehetnek általános metódusok vagy típusok típusparaméterei. Dinamikus szerelvények kibocsátásakor ilyen nyílt konstrukciójú típusok is használhatók. Vegyük például az Base és Derived osztályokat az alábbi kódban.
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
A dinamikus összeállításban Derived előállításához szükséges az alaptípus megalkotása. Ehhez hívja meg a MakeGenericType metódust egy Type objektumon, amely a Base osztályt képviseli, a generikus típusargumentumok Int32 valamint a típusparaméter VDerived használatával. Mivel a típusokat és az általános típusparamétereket egyaránt objektumok jelölik, egy mindkettőt tartalmazó tömb átadható a Type metódusnak.
Megjegyzés:
Egy olyan konstruktált típus, mint például Base<int, V> a kódkibocsátásakor hasznos, de nem hívhatja meg a metódust ezen a MakeGenericType típuson, mert nem általános típusdefiníció. A példányosítható zárt építésű típus létrehozásához először hívja meg a GetGenericTypeDefinition metódust, hogy lekérjen egy az általános típusdefiníciót képviselő Type objektumot, majd a kívánt típusargumentumokkal hívja meg a MakeGenericType metódust.
A Type visszaadott MakeGenericType objektum megegyezik az Type eredményül kapott létrehozott típus metódusának meghívásával GetType kapott objektummal, vagy GetType bármely olyan létrehozott típus metódusával, amely ugyanabból az általános típusdefinícióból lett létrehozva ugyanazzal a típusargumentumokkal.
Megjegyzés:
Az általános típusok tömbje önmagában nem általános típus. Nem hívhat meg MakeGenericType-et egy tömbtípuson, például C<T>[]-en (Dim ac() As C(Of T) a Visual Basicben). Zárt általános típus C<T>[]létrehozásához hívja GetElementType meg az általános típusdefiníciót; hívja meg C<T> az általános típusdefiníciót MakeGenericTypea létrehozott típus létrehozásához, és végül hívja meg a MakeArrayType metódust a létrehozott típuson a tömbtípus létrehozásához. Ugyanez igaz a mutatótípusokra és ref -típusokra (ByRef a Visual Basicben).
Az általános tükrözésben használt kifejezések invariáns feltételeinek listáját a IsGenericType tulajdonság megjegyzéseiben találja.
Beágyazott típusok
Ha egy általános típus c#, C++ vagy Visual Basic használatával van definiálva, akkor a beágyazott típusok mind általánosak. Ez akkor is igaz, ha a beágyazott típusok nem rendelkeznek saját típusparaméterekkel, mivel mindhárom nyelv tartalmazza a beágyazott típusok típusparamétereit a beágyazott típusok típusparaméter-listájában. Vegye figyelembe a következő osztályokat:
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
A beágyazott osztály Inner típusparaméter-listája két típusparamétert tartalmaz, T amelyek Uközül az első a beágyazott osztály típusparamétere. Hasonlóképpen, a beágyazott osztály Innermost1 típusparaméter-listája három típusparamétert tartalmaz: T, U és V, valamint T és U, amelyek a külső osztályaiból származnak. A beágyazott osztálynak Innermost2 két típusparamétere van, T és Uezek a beágyazott osztályokból származnak.
Ha a beágyazási típus paraméterlistája több típusparamétert is tartalmaz, az összes típusparaméter sorrendben szerepel a beágyazott típus típusparaméter-listájában.
Ha egy beágyazott típus általános típusdefiníciójából szeretne általános típust létrehozni, hívja meg MakeGenericType a metódust az összes beágyazott típus típusargumentumtömbjeinek összefűzésével létrehozott metódussal, kezdve a legkülső általános típussal, és a beágyazott típus típusargumentumtömbjével végződik, ha saját típusparaméterekkel rendelkezik. Ha létre szeretne hozni egy példányt Innermost1, hívja meg a MakeGenericType metódust egy három típust tartalmazó tömbtel, amelyet a T, az U és a V függvényhez kell hozzárendelni. Egy példány Innermost2létrehozásához hívja meg a MakeGenericType metódust egy két típust tartalmazó tömböt, amelyet A és U értékhez kell hozzárendelni.
A nyelvek így propagálják a beágyazási típusok típusparamétereit, így a beágyazott típusok mezőinek meghatározásához használhatja a beágyazott típus típusparamétereit. Ellenkező esetben a típusparaméterek nem lennének hatókörben a beágyazott típusok testén belül. Beágyazott típusok definiálhatók a beágyazási típusok típusparamétereinek propagálása nélkül, a kód dinamikus szerelvényekben való kibocsátásával vagy a Ilasm.exe (IL-összeállító) használatával. Vegye figyelembe a CIL-szerelvény következő kódját:
.class public Outer<T> {
.class nested public Inner<U> {
.class nested public Innermost {
}
}
}
Ebben a példában nem lehet típusmezőt T vagy U osztályt Innermostdefiniálni, mert ezek a típusparaméterek nem tartoznak a hatókörbe. Az alábbi összeszerelőkód olyan beágyazott osztályokat határoz meg, amelyek a C++, a Visual Basic és a C#-ban definiált módon viselkednek:
.class public Outer<T> {
.class nested public Inner<T, U> {
.class nested public Innermost<T, U, V> {
}
}
}
A Ildasm.exe (IL Disassembler) segítségével megvizsgálhatja a magas szintű nyelvekben definiált beágyazott osztályokat, és megfigyelheti ezt az elnevezési sémát.