开发者

Getting the type of an array of T, without specifying T - Type.GetType("T[]")

I am trying to create a type that refers to an array of a generic type, without specifying the generic type. That is, I would like to do the equivalent of Type.GetType("T[]").

I already know how to do this with a non-array type. E.g.

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

Here's some sample code that reproduces the problem.

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[])
    }
}

The output is:

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

I'd like to correct that last "(null)".

This will be used to get an overload of a function via reflections by specifying the method signature:

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

I've already gotten my code mostly working by filtering the result of GetM开发者_高级运维ethods(), so this is more of an exercise in knowledge and understanding.


Simple:

var arrayOfT = typeof(IEnumerable<>).GetGenericArguments()[0].MakeArrayType();


How about this?

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

examples:

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

EDIT

As Jonathan Dickinson points out, elementType.MakeArrayType(1) doesn't return the same type as elementType.MakeArrayType(). I won't modify the original code sample since anyway it doesn't answer the question.

The difference between Type.MakeArrayType(1) and Type.MakeArrayType() is that the latter returns a vector type -- which is necessarily 1-dimensional and zero-based -- while the former returns a multidimensional array type that happens to have rank 1. Instances of the returned type are not necessarily zero-based.

The vector type is indicated with a pair of square brackets (for example, System.Int32[]) while the rank-1 array type is indicated with a pair of square brackets containing an asterisk (for example, System.Int32[*]).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜