Sdílet prostřednictvím


Metoda System.Type.MakeGenericType

Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.

Tato MakeGenericType metoda umožňuje napsat kód, který přiřazuje konkrétní typy parametrům typu definice obecného typu, a tím vytvořit Type objekt, který představuje konkrétní vytvořený typ. Tento Type objekt můžete použít k vytvoření instancí za běhu vytvořeného typu.

Typy vytvořené pomocí MakeGenericType mohou být otevřené, to znamená, že některé jejich argumenty typu mohou být parametry typu uzavření obecných metod nebo typů. Takové otevřené konstruované typy můžete použít při generování dynamických sestavení. Představte si například třídy Base a Derived v následujícím kódu.

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

K vygenerování Derived v dynamickém sestavení je nutné vytvořit jeho základní typ. Chcete-li to provést, zavolejte metodu MakeGenericTypeType u objektu představující třídu Base, pomocí argumentů Int32 obecného typu a parametru V typu z Derived. Vzhledem k tomu, že typy i parametry obecného typu jsou reprezentovány Type objekty, lze metodě MakeGenericType předat pole obsahující obojí.

Poznámka:

Vytvořený typ, například Base<int, V> je užitečný při generování kódu, ale nelze volat metodu MakeGenericType pro tento typ, protože to není definice obecného typu. Chcete-li vytvořit uzavřený vytvořený typ, který lze vytvořit instanci, nejprve zavolejte metodu GetGenericTypeDefinitionType získat objekt představující definici obecného typu a potom volat MakeGenericType s argumenty požadovaného typu.

Objekt Type vrácený MakeGenericType je stejný jako Type získaný voláním GetType metody výsledného vytvořeného typu nebo GetType metody jakéhokoli vytvořeného typu vytvořeného ze stejné definice obecného typu pomocí stejných argumentů typu.

Poznámka:

Pole obecných typů není sám o sobě obecným typem. Nelze volat MakeGenericType typ pole, například C<T>[] (Dim ac() As C(Of T) v jazyce Visual Basic). Chcete-li vytvořit uzavřený obecný typ z C<T>[], volání GetElementType získat definici C<T>obecného typu ; volání MakeGenericType definice obecného typu vytvořit konstruovaný typ; a nakonec volání MakeArrayType metody na konstruovaný typ vytvořit typ pole. Totéž platí pro typy a ref typy ukazatelů (ByRef v jazyce Visual Basic).

Seznam invariantních podmínek pro termíny použité v obecné reflexi najdete v IsGenericType poznámkách k vlastnostem.

Vnořené typy

Pokud je obecný typ definován pomocí jazyka C#, C++ nebo Visual Basicu, jsou všechny jeho vnořené typy obecné. To platí i v případě, že vnořené typy nemají vlastní parametry typu, protože všechny tři jazyky obsahují parametry typu ohraničující typy v seznamech parametrů typu vnořených typů. Vezměte v úvahu následující třídy:

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

Seznam parametrů typu vnořené třídy Inner má dva parametry typu, T z Unichž první je parametr typu jeho nadřazené třídy. Podobně seznam parametrů typu vnořené třídy Innermost1 má tři parametry typu, TUa V, s T a U pochází z jeho uzavřených tříd. Vnořená třída Innermost2 má dva parametry typu, T a Ukteré pocházejí z jeho uzavřených tříd.

Pokud seznam parametrů ohraničujícího typu obsahuje více než jeden parametr typu, jsou všechny parametry typu v pořadí zahrnuty do seznamu parametrů typu vnořeného typu.

Chcete-li vytvořit obecný typ z definice obecného typu pro vnořený typ, zavolejte MakeGenericType metodu s polem vytvořeným zřetězením pole argumentů typu všech uzavřených typů, počínaje vnějším obecným typem a končící polem argumentů typu samotného vnořeného typu, pokud má vlastní parametry typu. Chcete-li vytvořit instanci Innermost1, zavolejte metodu MakeGenericType s polem obsahujícím tři typy, které mají být přiřazeny K T, U a V. Chcete-li vytvořit instanci Innermost2, volání MakeGenericType metody s polem obsahující dva typy, které mají být přiřazeny K T a U.

Jazyky tímto způsobem šíří parametry typu ohraničující typy, abyste mohli použít parametry typu ohraničujícího typu k definování polí vnořených typů. V opačném případě by parametry typu nebyly v oboru v rámci těla vnořených typů. Vnořené typy je možné definovat bez rozšíření parametrů typu ohraničujících typů tak, že vygenerujete kód v dynamických sestaveních nebo pomocí Ilasm.exe (IL Assembler). Představte si následující kód assembleru CIL:

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

V tomto příkladu není možné definovat pole typu T nebo U třídy Innermost, protože tyto parametry typu nejsou v oboru. Následující kód assembleru definuje vnořené třídy, které se chovají způsobem, jakým by byly definovány v jazyce C++, Visual Basic a C#:

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

Pomocí Ildasm.exe (IL Disassembler) můžete prozkoumat vnořené třídy definované v jazycích vysoké úrovně a sledovat toto schéma pojmenování.