Получение типа массива T без указания T - Type.GetType ("T []") - PullRequest
6 голосов
/ 13 января 2011

Я пытаюсь создать тип, который ссылается на массив универсального типа, без указания универсального типа. То есть я бы хотел сделать эквивалент Type.GetType("T[]").

Я уже знаю, как это сделать с типом, не являющимся массивом. Э.Г.

Type.GetType("System.Collections.Generic.IEnumerable`1")
// or
typeof(IEnumerable<>)

Вот пример кода, который воспроизводит проблему.

using System;
using System.Collections.Generic;

public class Program
{
    public static void SomeFunc<T>(IEnumerable<T> collection) { }

    public static void SomeArrayFunc<T>(T[] collection) { }

    static void Main(string[] args)
    {
        Action<Type> printType = t => Console.WriteLine(t != null ? t.ToString() : "(null)");
        Action<string> printFirstParameterType = methodName =>
            printType(
                typeof(Program).GetMethod(methodName).GetParameters()[0].ParameterType
                );

        printFirstParameterType("SomeFunc");
        printFirstParameterType("SomeArrayFunc");

        var iEnumerableT = Type.GetType("System.Collections.Generic.IEnumerable`1");
        printType(iEnumerableT);

        var iEnumerableTFromTypeof = typeof(IEnumerable<>);
        printType(iEnumerableTFromTypeof);

        var arrayOfT = Type.GetType("T[]");
        printType(arrayOfT); // Prints "(null)"

        // ... not even sure where to start for typeof(T[])
    }
}

Вывод:

System.Collections.Generic.IEnumerable`1[T]
T[]
System.Collections.Generic.IEnumerable`1[T]
System.Collections.Generic.IEnumerable`1[T]
(null)

Я бы хотел исправить это последнее "(ноль)".

Это будет использоваться для получения перегрузки функции через отражения путем указания сигнатуры метода:

var someMethod = someType.GetMethod("MethodName", new[] { typeOfArrayOfT });
// ... call someMethod.MakeGenericMethod some time later

Я уже заставил свой код в основном работать, отфильтровав результат GetMethods(), так что это больше упражнение в знании и понимании.

Ответы [ 2 ]

8 голосов
/ 13 января 2011

Простой:

var arrayOfT = typeof(IEnumerable<>).GetGenericArguments()[0].MakeArrayType();
1 голос
/ 13 января 2011

Как насчет этого?

Type MakeArrayType(Type elementType, int rank)
{
    return elementType.MakeArrayType(rank);
}

примеры:

var x = MakeArrayType(typeof(string), 1); // x == typeof(string[])
var y = MakeArrayType(typeof(float), 4);  // y == typeof(float[,,,])

РЕДАКТИРОВАТЬ

Как отмечает Джонатан Дикинсон, elementType.MakeArrayType (1) не возвращаетсятот же тип, что и elementType.MakeArrayType ().Я не буду изменять исходный пример кода, так как в любом случае он не отвечает на вопрос.

Разница между Type.MakeArrayType (1) и Type.MakeArrayType () состоит в том, что последний возвращает векторный тип -который обязательно является одномерным и начинается с нуля - тогда как первый возвращает многомерный тип массива, который имеет ранг 1. Экземпляры возвращаемого типа не обязательно начинаются с нуля.

Тип вектора указанс парой квадратных скобок (например, System.Int32[]), в то время как тип массива ранга 1 указывается парой квадратных скобок, содержащих звездочку (например, System.Int32[*]).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...