Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 GetMethods(), so this is more of an exercise in knowledge and understanding.

like image 621
Merlyn Morgan-Graham Avatar asked Jan 12 '11 23:01

Merlyn Morgan-Graham


People also ask

How do you find the type of an array?

Array types may be identified by invoking Class. isArray() . To obtain a Class use one of the methods described in Retrieving Class Objects section of this trail.

What is GetType () name in C#?

The GetType() method of array class in C# gets the Type of the current instance. To get the type. Type tp = value. GetType(); In the below example, we are checking the int value using the type.

How do you get type objects from assemblies that are already loaded?

Use Type. GetType to get the Type objects from an assembly that is already loaded.


2 Answers

Simple:

var arrayOfT = typeof(IEnumerable<>).GetGenericArguments()[0].MakeArrayType();
like image 130
Enigmativity Avatar answered Sep 22 '22 00:09

Enigmativity


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[*]).

like image 31
phoog Avatar answered Sep 18 '22 00:09

phoog