Sdílet prostřednictvím


Reflexe a obecné typy

Z pohledu reflexe spočívá rozdíl mezi obecným typem a konkrétním typem v tom, že obecný typ má přidruženou sadu parametrů typu (pokud se jedná o definici obecného typu) nebo argumenty typu (pokud se jedná o konstruovaný typ). Obecná metoda se liší od běžné metody stejným způsobem.

Existují dva klíče k pochopení způsobu, jakým reflexe zpracovává obecné typy a metody:

  • Parametry typu definice obecného typu a definice obecných metod jsou reprezentovány instancemi Type třídy.

    Poznámka:

    Mnoho vlastností a metod Type má různé chování, když Type objekt představuje parametr obecného typu. Tyto rozdíly jsou popsané v článcích o vlastnosti a metodě. Například viz IsAutoClass a DeclaringType. Některé členy jsou navíc platné pouze v případě, že Type objekt představuje parametr obecného typu. Podívejte se například na GetGenericTypeDefinition.

  • Pokud instance Type představuje obecný typ, zahrnuje pole typů, které představují parametry typu (pro definice obecného typu) nebo argumenty typu (pro vytvořené typy). Totéž platí pro instanci MethodInfo třídy, která představuje obecnou metodu.

Reflexe poskytuje metody Type , MethodInfo které umožňují přístup k poli parametrů typu a k určení, zda instance Type představuje parametr typu nebo skutečný typ.

Například kód demonstrující zde probírané metody najdete v tématu Postupy: Prozkoumání a vytvoření instance obecných typů pomocí reflexe.

V následující diskuzi se předpokládá znalost terminologie obecných typů, například rozdíl mezi parametry typu a argumenty a otevřenými nebo uzavřenými vytvořenými typy. Další informace najdete v tématu Obecné typy.

Jedná se o obecný typ nebo metodu?

Když použijete reflexi k prozkoumání neznámého typu reprezentovaného instancí Type, použijte vlastnost IsGenericType k určení, zda je tento typ obecným. true Vrátí, pokud je typ obecný. Podobně když prozkoumáte neznámou metodu reprezentovanou instancí MethodInfo třídy, použijte IsGenericMethod vlastnost k určení, zda je metoda obecná.

Jedná se o obecný typ nebo definici metody?

IsGenericTypeDefinition Pomocí vlastnosti určete, zda Type objekt představuje definici obecného typu, a pomocí IsGenericMethodDefinition metody určit, zda MethodInfo představuje definici obecné metody.

Definice obecného typu a metody jsou šablony, ze kterých se vytvářejí okamžité typy. Obecné typy v knihovnách .NET, například Dictionary<TKey,TValue>, jsou definice obecného typu.

Je typ nebo metoda otevřená nebo uzavřená?

Obecný typ nebo metoda je uzavřený, pokud zaměnitelné typy nahradily všechny jeho parametry typu, včetně všech parametrů typu všech obklopujících typů. Instanci obecného typu můžete vytvořit pouze v případě, že je zavřená. Vlastnost Type.ContainsGenericParameters vrátí true , pokud je typ otevřen. U metod metoda MethodBase.ContainsGenericParameters provádí stejnou funkci.

Generování uzavřených obecných typů

Jakmile máte obecný typ nebo definici metody, použijte metodu MakeGenericType k vytvoření uzavřeného obecného typu nebo metodu MakeGenericMethod k vytvoření uzavřené obecné metody pomocí MethodInfo.

Získání definice obecného typu nebo metody

Pokud máte otevřený obecný typ nebo metodu, která není obecným typem nebo definicí metody, nemůžete vytvořit jeho instance a nemůžete zadat parametry typu, které chybí. Musíte mít obecný typ nebo definici metody. Proveďte metodu GetGenericTypeDefinition pro získání definice obecného typu nebo metodu GetGenericMethodDefinition pro získání definice obecné metody.

Například pokud máte objekt představující Type a chcete vytvořit typ Dictionary<int, string>, můžete použít metodu Dictionary<string, MyClass>GetGenericTypeDefinition k získání reprezentace Type a pak použít metodu Dictionary<TKey, TValue> k vytvoření reprezentace MakeGenericTypeType.Dictionary<int, MyClass>

Příklad otevřeného obecného typu, který není obecným typem, naleznete v části Typ parametru nebo argumentu typu.

Prozkoumání argumentů typu a parametrů typu

Použijte metodu Type.GetGenericArguments k získání pole Type objektů, které představují parametry typu nebo argumenty typu obecného typu, a použijte metodu MethodInfo.GetGenericArguments provést totéž pro obecnou metodu.

Jakmile víte, že Type objekt představuje parametr typu, reflexe může odpovědět na mnoho dalších otázek. Můžete určit zdroj parametru typu, jeho umístění a jeho omezení.

Typ parametru nebo argument typu

Chcete-li zjistit, zda určitý prvek pole je parametr typu nebo typ argument, použijte IsGenericParameter vlastnost. Vlastnost IsGenericParameter je true , pokud je element parametrem typu.

Obecný typ lze otevřít bez definice obecného typu, v takovém případě má kombinaci argumentů typu a parametrů typu. Například v následujícím kódu je třída D odvozena z typu vytvořeného nahrazením prvního parametru typu D druhým parametrem typu B.

class B<T, U> {}
class D<V, W> : B<int, V> {}
Class B(Of T, U)
End Class
Class D(Of V, W)
    Inherits B(Of Integer, V)
End Class

Pokud získáte Type objekt představující D<V, W> a použijete BaseType vlastnost k získání základního typu, výsledek type B<int, V> je otevřený, ale nejedná se o definici obecného typu.

Zdroj obecného parametru

Parametr obecného typu může pocházet z typu, který zkoumáte, z uzavřeného typu nebo z obecné metody. Zdroj parametru obecného typu můžete určit následujícím způsobem:

  • Nejprve pomocí DeclaringMethod vlastnosti určete, zda parametr typu pochází z obecné metody. Pokud hodnota vlastnosti není odkazem typu null, pak je zdrojem obecná metoda.
  • Pokud zdroj není obecnou metodou, použijte DeclaringType vlastnost k určení obecného typu, do které parametr obecného typu patří.

Pokud parametr typu patří do obecné metody, DeclaringType vrátí vlastnost typ, který deklaroval obecnou metodu, což je irelevantní.

Pozice obecného parametru

Ve výjimečných situacích je nutné určit pozici parametru typu v seznamu parametrů typu deklarující třídy. Předpokládejme například, že máte Type objekt představující B<int, V> typ z předchozího příkladu. Metoda GetGenericArguments poskytuje seznam argumentů typu a při prozkoumání V můžete použít DeclaringMethod a DeclaringType vlastnosti zjistit, odkud pochází. Vlastnost pak můžete použít GenericParameterPosition k určení jeho pozice v seznamu parametrů typu, kde byla definována. V tomto příkladu je na pozici 0 (nula) v seznamu parametrů typu, V kde byla definována.

Základní typ a omezení rozhraní

GetGenericParameterConstraints Pomocí metody získejte omezení základního typu a omezení rozhraní parametru typu. Pořadí prvků pole není významné. Prvek představuje omezení rozhraní, pokud se jedná o typ rozhraní.

Obecné atributy parametrů

Vlastnost GenericParameterAttributes získá GenericParameterAttributes hodnotu, která označuje odchylku (kovariance nebo kontravariance) a zvláštní omezení parametru typu.

Kovariance a kontravariance

Chcete-li zjistit, zda je parametr typu kovariantní nebo kontravariant, použijte masku GenericParameterAttributes.VarianceMask na GenericParameterAttributes hodnotu vrácenou GenericParameterAttributes vlastností. Pokud je výsledkem GenericParameterAttributes.None, parametr typu je invariantní. Další informace naleznete v tématu Kovariance a Kontravariance.

Zvláštní omezení

Chcete-li určit zvláštní omezení typu parametru, aplikujte masku GenericParameterAttributes.SpecialConstraintMask na hodnotu GenericParameterAttributes, kterou vrací vlastnost GenericParameterAttributes. Pokud je GenericParameterAttributes.None výsledkem, neexistují žádná zvláštní omezení. Parametr typu může být omezen na odkazový typ, být nenulový typ hodnoty a mít konstruktor bez parametrů.

Invariants

Tabulku invariantních podmínek pro běžné výrazy v reflexi generických typů naleznete v části Type.IsGenericType. Další termíny týkající se obecných metod naleznete v tématu MethodBase.IsGenericMethod.