C # отражают тип с переменным числом параметров типа

#c# #generics #reflection

#c# #обобщения #отражение

Вопрос:

Возможно ли получить во время выполнения тип универсального класса, который имеет переменное количество параметров типа?

То есть, на основе числа, можем ли мы получить тип кортежа с таким количеством элементов?

Type type = Type.GetType("System.Tuple<,>");

Ответ №1:

Способ записать это

 Type generic = Type.GetType("System.Tuple`2");
  

Формат обобщенных типов прост:

 "Namespace.ClassName`NumberOfArguments"
  

` — это символ 96. (ALT 96).

Однако я бы избегал использования строк, это медленнее, чем использование typeof или, что лучше, поиска по массиву. Я бы предоставил хорошую статическую функцию, которая в тысячу раз быстрее…

 private static readonly Type[] generictupletypes = new Type[]
{
    typeof(Tuple<>),
    typeof(Tuple<,>),
    typeof(Tuple<,,>),
    typeof(Tuple<,,,>),
    typeof(Tuple<,,,,>),
    typeof(Tuple<,,,,,>),
    typeof(Tuple<,,,,,,>),
    typeof(Tuple<,,,,,,,>)
};

public static Type GetGenericTupleType(int argumentsCount)
{
    return generictupletypes[argumentsCount];
}
  

Комментарии:

1. Хах, я видел, как они были названы в IL, что я был достаточно глуп, чтобы пропустить это, когда отражение безумно! Спасибо!

2. 🙂 нет, вы не были глупы, это противоречит здравому смыслу, я согласен с вами.

3. Что касается оптимизации, вы, вероятно, правы. В настоящее время я пишу компилятор, который может иметь дело с несколькими универсальными классами, но предоставление таблиц поиска для общих типов может быть весьма полезным

Ответ №2:

Попробуйте это:

 using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

public class MainClass 
{
    public static void Main()
    {
        PrintTypeParams(typeof(Tuple<int, double, string>));
    }

    private static void PrintTypeParams(Type t)
    {
        Console.WriteLine("Type FullName: "   t.FullName);
        Console.WriteLine("Number of arguments: "   t.GetGenericArguments().Length);
        Console.WriteLine("List of arguments:");
        foreach (Type ty in t.GetGenericArguments())
        {
            Console.WriteLine(ty.FullName);
            if (ty.IsGenericParameter)
            {
                Console.WriteLine("Generic parameters:");
                Type[] constraints = ty.GetGenericParameterConstraints();
                foreach (Type c in constraints)
                Console.WriteLine(c.FullName);
            }
        }
    }
}
  

Вывод:

  Type FullName: System.Tuple`3[[System.Int32, mscorlib, Version=4.0.0.0, Culture=
 neutral, PublicKeyToken=b77a5c561934e089],[System.Double, mscorlib, Version=4.0.
 0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib,
 Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
 Number of arguments: 3
 List of arguments:
 System.Int32
 System.Double
 System.String