2011-01-12 6 views
6

ジェネリック型を指定せずにジェネリック型の配列を参照する型を作成しようとしています。つまり、私はType.GetType("T[]")と同等のことをしたいと思います。T - Type.GetType( "T []")を指定せずに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()の結果をフィルタリングすることにより、作業の私のコードを得ているので、これはもっとあります知識と理解の練習の

答えて

8

シンプル:これについて

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

ニース。私はそれを自分で考えなかったでしょう。 –

+0

+1:まだ少し厄介です( 'IEnumerable <>'は単なる例であり、ターゲットコードとの関連性はありません)が、これは魅力的です:) '' Type.GetType( " T ")'? –

+0

これは、IEnumerable のT型パラメータがSomeFunc ()のものと同じではないため、メソッドにバインドするのに役立ちません。 – phoog

1

どのように?

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

EDIT

ジョナサン・ディッキンソンが指摘するように、elementType.MakeArrayType(1))(elementType.MakeArrayTypeと同じタイプを返しません。とにかく質問に答えないので、私は元のコードサンプルを変更しません。

Type.MakeArrayType(1)とType.MakeArrayType()の違いは、前者が必ず1次元とゼロベースのベクトル型を返すことです。戻り値の型のインスタンスは必ずしもゼロベースであるとは限りません。

ベクトルタイプは、角括弧(たとえば、System.Int32[])で示され、ランク1の配列タイプは、アスタリスクを含む一対の角かっこ(たとえば、System.Int32[*])で示されます。

+0

これは終わりですが、私が欲しいものではありません。私は特にT []が必要です。なぜこのタイプを質問の最後に使用したいのかを見てください。 –

+2

母は 'MakeArrayType(typeof(string)、1)' *実際には 'typeof(string).MakeArrayType(1)'よりも優れていますか? –

+0

@ダン・タオ:特にそうではありません – phoog

関連する問題