2012-09-29 14 views
6

ben soru işareti yerine ne yapacağını bilmiyorum buGenel bir yöntemin T türünün IEnumerable <> olup olmadığını nasıl kontrol edersiniz?

void DoSomething<T>(T param) 
{ 
    if param is IEnumerable<?> 
    { 
     loop param and do stuff 
    } 
} 

böyle bir şey yapmak istiyorum. Ve bu mümkün mü?

if (T is IEnumerable) { .. } 

ancak T her zaman IEnumerable olmasını bekliyoruz eğer yapabilirsiniz:

+0

ise 'param',' 'IEnumerable türde değil bir şey yapmak istiyorsun? Değilse, neden 'T'' IEnumerable 'türünde [nerede] (http://msdn.microsoft.com/en-us/library/bb384067.aspx)? Burada –

+0

Olası cevaplar: yığın taşması görevde http://stackoverflow.com/questions/1846671/determine-if-collection-is-of-type-ienumerablet –

+0

Cevap [1] [tıklayınız] [1]: http://stackoverflow.com/questions/906499/getting-type-t-from-ienumerablet –

cevap

7

Ne arıyorsun olduğunu

void DoSomething<T>(T param) where T : IEnumerable 
{ 
    foreach (var t in param) { ... } 
} 

veya IEnumerable içindeki değerlerin türünü denetlemek :

public void DoSomething<T,U>(T val) where T : IEnumerable<U> 
{ 
    foreach (U a in val) 
    { 
    } 
} 

Kendiniz kontrol etmek için endişelenmenize gerek kalmadan derleyici bunu sizin için yapar. Birkaç yolu vardır :)

+0

Sanırım, aslında, sadece genel bir IEnumerable değil, belirli bir türdeki IEnumerable'ı kontrol etmeye çalışıyor. Sorunun altındaki yorumdaki bağlantı bu senaryoyu ele alır. –

+0

İyi nokta. Yanıtı bu senaryoyla tamamlarım, teşekkürler. –

+0

İyi yanıt için teşekkürler. Sorun şu ki, T'nin her zaman IEnumerable olmasını beklemiyorum. Aslında, zaten bir yöntem 'geçersiz ProcessList (IEnumerable listesi)' ve argüman IEnumerable ise 'DoSomething() 'içinde yeniden kullanmak istiyorum. – tranmq

0

statik tip sistemi ve derleyici sahip güzel şeylerden biridir:

void DoSomething<T>(T param) 
{ 
    if (param is IEnumerable) 
    { 
     foreach (var item in (IEnumerable)param) 
     { 
      // Do something 
     } 
    } 
} 

void DoSomething<T>(T param) 
{ 
    if (param is IEnumerable<string>) 
    { 
     foreach (var item in (IEnumerable<string>)param) 
     { 
      // Do something 
     } 
    } 
} 

void DoSomething<T,TItem>(T param) 
{ 
    if (param is IEnumerable<TItem>) 
    { 
     foreach (var item in (IEnumerable<TItem>)param) 
     { 
      // Do something 
     } 
    } 
} 
+0

En iyi uygulama, '' '' '' '-artı-direct-cast yerine' '' is-plus-direct-cast iki kez yaparsa, pahalı çalışma zamanı tipi denetimi sadece bir kez yapar. – phoog

0

Her arayüzün açık genel tür kontrol etmeleri sınıfının uyguladığı gibi böylece:

bool implements = typeof(T).GetInterfaces().Where(t => t.IsGenericType && 
    t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).Any(); 

Bu, bir tür aslında tip T ne olduğunu bilmeden IEnumerable<T> uygulayan olup olmadığını belirlemek için izin verecektir. Türün IEnumerable<T>'u birden çok kez uygulayabildiğini unutmayın.

IEnumerable<T> için tip parametreleri olan sıra dizisini istiyorsanız, yukarıdaki sorguyu aşağıdaki gibi değiştirebilirsiniz;

IEnumerable<Type> types = typeof(T).GetInterfaces(). 
    Where(t => t.IsGenericType && 
     t.GetGenericTypeDefinition() == typeof(IEnumerable<>)). 
    Select(t => t.GetGenericArguments()[0]); 
+0

IEnumerable 'işlevini uygulayan bir tür, gerçekten çok korkutucu bir türdür. – phoog

İlgili konular