Looking for c# Keywords? Try Ask4Keywords

C# Language Определение общих аргументов экземпляров родовых типов


пример

Если у вас есть экземпляр родового типа, но по какой-то причине не знаю определенного типа, вы можете определить общие аргументы, которые были использованы для создания этого экземпляра.

Предположим, кто-то создал экземпляр List<T> и передал его методу:

var myList = new List<int>();
ShowGenericArguments(myList);

где ShowGenericArguments имеет эту подпись:

public void ShowGenericArguments(object o)

поэтому во время компиляции вы не знаете, какие общие аргументы были использованы для создания o . Отражение предоставляет множество методов для проверки типичных типов. Сначала мы можем определить, является ли тип o общим типом:

public void ShowGenericArguments(object o)
{
    if (o == null) return;

    Type t = o.GetType();
    if (!t.IsGenericType) return;
    ...

Type.IsGenericType возвращает true если тип является общим типом и false если нет.

Но это еще не все, что мы хотим знать. List<> сам также является общим типом. Но мы хотим только изучить экземпляры конкретных построенных общих типов. Построенный общий тип - это, например, List<int> который имеет аргумент определенного типа для всех его общих параметров .

Класс Type предоставляет еще два свойства: IsConstructedGenericType и IsGenericTypeDefinition , чтобы отличать эти построенные общие типы от общих описаний типов:

typeof(List<>).IsGenericType // true
typeof(List<>).IsGenericTypeDefinition // true
typeof(List<>).IsConstructedGenericType// false

typeof(List<int>).IsGenericType // true
typeof(List<int>).IsGenericTypeDefinition // false
typeof(List<int>).IsConstructedGenericType// true

Чтобы перечислить общие аргументы экземпляра, мы можем использовать метод GetGenericArguments() который возвращает массив Type содержащий аргументы общего типа:

public void ShowGenericArguments(object o)
{
    if (o == null) return;   
    Type t = o.GetType();
    if (!t.IsConstructedGenericType) return;

    foreach(Type genericTypeArgument in t.GetGenericArguments())
        Console.WriteLine(genericTypeArgument.Name);
}

Таким образом, вызов сверху ( ShowGenericArguments(myList) ) приводит к этому выводу:

Int32