我如何从ICollection有一个未知的T

本文关键字:有一个 未知 ICollection | 更新日期: 2023-09-27 18:16:16

我的代码如下:

//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>中取出?

我如何从ICollection<T>有一个未知的T

如果没有ICollection<T>的封闭类型,您将不得不求助于反射来调用Count属性。

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

你必须使用反射:

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);   
}

反射将是一种方式,但请记住,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实际上生成了一个数组,除了在运行时继承了这些类的泛型版本之外,还继承了非泛型版本),所以你上面的代码也可以处理数组。

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

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

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

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