2011-11-29 23 views
4

这里是我到目前为止的代码:如何获得自ICollection <T>计数与未知牛逼

//TODO: Look for a way of handling ICollection<T> 

if (value is ICollection) 
{ 
    return CreateResult(validationContext, ((ICollection)value).Count); 
} 

if (value is IEnumerable) 
{ 
    var enumerator = ((IEnumerable)value).GetEnumerator(); 
    try 
    { 
     var count = 0; 
     while (enumerator.MoveNext()) 
      count++; 
     return CreateResult(validationContext, count); 
    } 
    finally 
    { 
     if (enumerator is IDisposable) 
      ((IDisposable)enumerator).Dispose(); 
    } 

} 

有没有得到CountICollection<T>而不诉诸遍历集合的好办法吗?

回答

1

的反思将是要走的路,但请记住,大部分在FCL收藏的来自ICollection<T>ICollection所以代码继承喜欢这个作品:

var collection = new List<int>(); 
Console.WriteLine(collection is ICollection<MyClass>); 
Console.WriteLine(collection is ICollection); 

True是为两者输出。这适用于FCL中大多数(如果不是全部的话)收藏。如果您需要它来处理自定义集合或不实现ICollection的集合,则反射是唯一的方法。

旁注:数组也隐含地实现了ICollection,IList和IEnumerable(CLR实际上生成一个继承自那些类的通用版本的数组,除了在运行时是非泛型的),所以你的上面的代码可以处理数组以及。

+0

奇怪。在发布这个问题之前,我看了一下,我可以发誓,我没有看到列表的接口列表中的ICollection。也许我正在看IList 。 –

+0

当'collection'是一个List,但是如果我的类型真的是未知的,就像System.Object那么它将不起作用,除非提供了。 –

5

如果没有ICollection<T>的封闭类型,则必须使用反射来调用Count属性。

if (typeof(ICollection<>) == value.GenericTypeDefinition()) { 
    var countProp = value.GetType().GetProperty("Count"); 
    var count = (int)countProp.GetValue(value, null); 
} 
+0

或者使用['dynamic'](http://msdn.microsoft.com/en-us/library/ dd264736.aspx)做同样的事情。 –

+0

@ MerlynMorgan-Graham:动态是特定于Visual Studio的,而不是.NET –

+0

@nic:我链接的文章可能会让某人对每种语言版本所带来的内容都不熟悉,但这种方式似乎是这样的,但我向你保证 - 它是C#4功能,而不是“视觉工作室”功能。这就是说,不知道它是否以VB.Net中的某种形式提供)但问题上的标签说C#,而不仅仅是.net –

4

你将不得不使用反射:

var genCollType = value.GetType() 
         .GetInterfaces() 
         .FirstOrDefault 
          (i => i.IsGenericType 
           && i.GetGenericTypeDefinition() == typeof(ICollection<>)); 

if (genCollType != null) 
{ 
    int count = (int)genCollType.GetProperty("Count") 
           .GetValue(value, null); 

    return CreateResult(validationContext, count); 
} 
-1

ICollection和IEnumerable接口都具有Count属性。通用版本也是如此。

if (value is ICollection) 
{ 
    return CreateResult(validationContext, ((ICollection)value).Count); 
} 

if (value is IEnumerable) 
{ 
    return CreateResult(validationContext, ((IEnumerable)value).Count); 
} 

MSDN文档的ICollection http://msdn.microsoft.com/en-us/library/system.collections.icollection.aspx

MSDN文档的IEnumerable http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx

+0

IEnumerable没有Count属性,它只有一个扩展方法Count()。 –

+0

我甚至没有看到IEnumerable.Count的扩展方法。我确实看到一个IEnumerable .Count。 –

+0

我可能一直在看IEnumerable ,但戴夫有一个好点。为什么你不能使用扩展方法? –