Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 测试类型是否为集合的最佳方法_C#_.net_Ienumerable - Fatal编程技术网

C# 测试类型是否为集合的最佳方法

C# 测试类型是否为集合的最佳方法,c#,.net,ienumerable,C#,.net,Ienumerable,我有一个方法,它接受System.Object类型的参数obj 现在我想检查obj的实际类型是否为: 集合类型(IEnumerable) 还有别的吗 我想到的第一个方法是: if (obj is IEnumerable) // obj is a collection 但是System.String实现了IEnumerable,并且我不想将字符串视为一个集合 我认为的第二种方法是测试ICollection而不是IEnumerable,因为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

有更好的方法吗?

如果您真的只想测试:

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

但是坦率地说,如果你真的只想使用特殊的
string
(顺便问一下,为什么?)。如果您测试
ICollection
,您将把LINQ查询的结果视为“非收集”,例如,没有充分的理由。

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

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

如果要对任何列表/集合/IEnumerable执行检查并为tpyes(包括null)获取true,但对字符串类型获取false,则

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

这似乎是唯一的办法。我想当BCL的人设计字符串类型时,他们没有意识到IEnumerable作为引用任何集合的唯一方式会变得多么重要。我将可枚举项视为序列,而不是集合。这里的意思可能有细微的差别;因为我不知道你的申请,我不知道这是否相关。我们在设计集合初始值设定项时遇到了这个问题。有很多“集合”没有实现ICollection,还有很多对象实现了Add,但它们不是集合。(通常是数学对象)我们决定使用启发式。如果一个类型同时实现IEnumerable并具有公共Add方法,那么它可能是一个集合。这有点愚蠢,但在实践中它是有效的。这是一个很好的关于集合抽象的相关资源:或者
obj.GetType().GetInterface(“System.Collections.IEnumerable”)!=空