关于c#:测试Type是否为集合的最佳方法

Best way to test if a Type is a collection

我有一个方法接受System.Object类型的参数obj

现在我想检查obj的实际类型是否是:

  • 集合类型(IEnumerable)。
  • 别的。

我首先想到的是:

1
2
if (obj is IEnumerable)
   // obj is a collection

但System.String实现了IEnumerable,我不想将String视为集合。

我认为第二种方法是测试ICollection而不是IEnumerable,因为IEnumerable更像是一个潜在的集合,而不是实际的集合。这将省去字符串,但也省去了ICollection-of-T,因为它不继承ICollection(IEnumerable-of-T是唯一向后兼容的通用集合抽象,它继承了IEnumerable)。

所以我想最好的办法是:

1
2
3
4
5
6
if (obj is string)
  // not a collection
else if (obj is IEnumerable)
  // collection
else
  // not a collection

有更好的方法吗?


我觉得你把这件事弄得有点复杂了。如果您真的想使用IEnumerable但不包括System.String,为什么不直接在代码中这样做呢?

1
2
3
public static bool IsCollection(object obj) {
  return obj is IEnumerable && !(obj is String);
}


如果您真的只想测试:

1
2
bool isCollection = obj.GetType().GetInterfaces()
    .Any(iface => iface.GetGenericTypeDefinition() == typeof(ICollection<>))

但坦率地说,如果你真的只想特例string(顺便问一下,为什么?),那么就这么做。如果您测试ICollection<>,您将把LINQ查询的结果视为"非集合",例如,没有好的理由。