2011-01-12 25 views
6

belirtmeden bir T türünün türünü elde etme Genel tür belirtmeden, bir genel tür dizisini ifade eden bir tür oluşturmaya çalışıyorum. Yani, Type.GetType("T[]") eşdeğerini yapmak istiyorum.T - Type.GetType ("T []")

Bunu bir dizi dışı türüyle nasıl yapacağımı biliyorum. Örneğin.

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

Sorunu yeniden üreten bazı örnek kodlar.

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

çıktısı:

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

I "(null değeri)" bu son düzeltmek istiyorum. Zaten çoğunlukla GetMethods() sonucunu filtreleyerek çalışan kodumu ele verdik

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

, bu nedenle bu fazlasıdır:

Bu

yöntem imzası belirterek yansımaları üzerinden bir fonksiyonun bir aşırı almak için kullanılacak bilgi ve anlayış içinde bir egzersiz.

cevap

8

Basit:

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

Güzel. Bunu kendim düşünmezdim. –

+0

+1: Hala biraz dağınık (çünkü IEnumerable <> 'sadece bir örnekti - hedef kodumda bir alakası yok), ama bu bir cazibe gibi çalışıyor :) 'Type.GetType (") almanın daha temiz bir yolu var mı? T ')'? –

+0

Bu, yöntemlere bağlamanıza yardımcı olmaz, çünkü IEnumerable 'daki T tipi parametresi, SomeFunc () öğesindekiyle aynı T değildir. – phoog

1

nasıl?

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

örnek:

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

DÜZENLEME

Jonathan Dickinson işaret ettiği gibi, elementType.MakeArrayType (1) elementType.MakeArrayType aynı türde döndürmez(). Orijinal kod örneğini değiştirmeyeceğim, çünkü soruya cevap vermiyor.

Type.MakeArrayType (1) ve Type.MakeArrayType (arasındaki fark) olduğu ikinci döner bir vektör türü - zorunlu 1 boyutlu ve sıfır tabanlı - eski getiri ise çok boyutlu bir dizi türü olduğu rütbe 1'e sahip olur. Döndürülen türün örnekleri mutlaka sıfır temelli değildir.

Vektör tipi, bir çift köşeli parantezle (örneğin, System.Int32[]) belirtilirken, sıra-1 dizi tipi yıldız işareti içeren bir çift köşeli parantez ile gösterilir (örneğin, System.Int32[*]).

+0

Bu yakın ama istediğim kadar değil. Özellikle T'ye ihtiyacım var []. Sorunun en alt kısmında bu türü neden kullanmak istediğimi görün. –

+2

Haha, 'MakeArrayType (typeof (string), 1)' * * gerçekten * typeof (string) .MakeArrayType (1) 'dan daha iyi? –

+0

@Dan Tao: Özellikle değil – phoog