测试Type是否为集合的最佳方法

时间:2009-07-24 23:27:04

标签: c# .net ienumerable

我有一个方法接受System.Object

类型的参数 obj

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

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

我想到的第一种方式是:

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

但是System.String实现了IEnumerable,而我不想将字符串视为集合

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

所以我猜最好的方法是:

if (obj is string) 
  // not a collection
else if (obj is IEnumerable) 
  // collection
else
  // not a collection

有更好的方法吗?

3 个答案:

答案 0 :(得分:7)

我认为你有点过于复杂了。如果你真的想使用IEnumerable但排除System.String,为什么不直接在代码中这样做呢?

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

答案 1 :(得分:5)

如果你真的只想测试:

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

但坦率地说,如果你真的只想要特殊情况string(为什么顺便说一下?),那么就这样做吧。如果您测试ICollection<>,则会将LINQ查询的结果视为“非集合”,例如,没有充分理由。

答案 2 :(得分:-1)

如果您想进行检查并确保任何列表/集合/ IEnumerable的tpyes(包括nullables)为true,但是对于字符串类型为false,则

   private static bool IsIEnumerable(Type requestType)
   {
      var isIEnumerable = typeof(IEnumerable).IsAssignableFrom(requestType);
      var notString = !typeof(string).IsAssignableFrom(requestType);
      return isIEnumerable && notString;
   }