2012-06-02 76 views
25

我想確定運行時類型是否是某種集合類型。我在下面的工作,但似乎很奇怪,我必須命名我認爲是數組中的集合類型的類型,就像我所做的那樣。如何確定一個類型是否是一種類型的集合?

在下面的代碼中,泛型邏輯的原因是因爲在我的應用程序中,我期望所有集合都是通用的。

bool IsCollectionType(Type type) 
{ 
    if (!type.GetGenericArguments().Any()) 
     return false; 

    Type genericTypeDefinition = type.GetGenericTypeDefinition(); 
    var collectionTypes = new[] { typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>), typeof(List<>) }; 
    return collectionTypes.Any(x => x.IsAssignableFrom(genericTypeDefinition)); 
} 

我該如何將此代碼重構爲更智能還是更簡單?

+0

有一點要記住的是,你通常不想考慮'string'作爲'char's集合,儘管它實現IEnumerable的''。 – svick

回答

48

真的所有這些類型繼承IEnumerable。您只能檢查它:

bool IsEnumerableType(Type type) 
{ 
    return (type.GetInterface(nameof(IEnumerable)) != null); 
} 

,或者如果你真的需要檢查的ICollection:

bool IsCollectionType(Type type) 
{ 
    return (type.GetInterface(nameof(ICollection)) != null); 
} 

看 「語法」 部分:

+0

哈哈。這確實很簡單。出於某種原因,我認爲這是行不通的,我沒有嘗試。 –

+1

文檔中的繼承層次結構不會告訴您實現的接口。但看看語法部分。 – svick

+0

@svick:那 公共類List :IList的,ICollection的, \t的IEnumerable ,IList的,ICollection的,IEnumerable的 ? – Ruben

2

您可以使用此輔助方法來檢查,如果一個類型實現一個開放的通用接口。你的情況,你可以使用DoesTypeSupportInterface(type, typeof(Collection<>))

public static bool DoesTypeSupportInterface(Type type,Type inter) 
{ 
    if(inter.IsAssignableFrom(type)) 
     return true; 
    if(type.GetInterfaces().Any(i=>i. IsGenericType && i.GetGenericTypeDefinition()==inter)) 
     return true; 
    return false; 
} 

或者你可以簡單地檢查非通用IEnumerable。所有集合接口都從它繼承。但我不會調用任何實現IEnumerable集合的類型。

+0

或使用解決方案[在這裏找到](http://stackoverflow.com/a/1075059/122781)除了泛型接口之外還適用於泛型類型。 – HappyNomad

1

他們都繼承了IEnumerable(),這意味着檢查its there應該足夠:

+3

因此,字符串導致誤報 – War

0

您可以使用LINQ,搜索的界面名稱,如

yourobject.GetType().GetInterfaces().Where(s => s.Name == "IEnumerable") 

如果有值是一個實例IEnumerable

+3

所以字符串導致誤報 – War

2

我知道這個線程很老,但根據Microsoft is關鍵字,這裏是一個現代示例,截至2015年7月20日。

if(collection is ICollection) return true; 
+0

問題是如何確定*類型*是一個集合,而不是一個對象實例。 –

相關問題