In .NET generic interface ICollection<T>
has Count
property itself. But it does not inherit any non-generic interface with a Count
property.
So, now if you want determine count of non-generic IEnumerable
, you have to check whether it is implementing ICollection
and if not, you have to use reflection to lookup whether it does implement generic ICollection<X>
, since you do not know the generic argument X
.
If ICollection<T>
cannot inherit from directly from ICollection
, why there is not another non-generic interface with Count
property only?
Is it just bad design choice?
UPDATE: To make the question more clear, I demonstrate the issue on my current implementation:
static int? FastCountOrZero(this IEnumerable items)
{
if (items == null)
return 0;
var collection = items as ICollection;
if (collection != null)
return collection.Count;
var source = items as IQueryable;
if (source != null)
return QueryableEx.Count(source);
// TODO process generic ICollection<> - I think it is not possible without using reflection
return items.Cast<object>().Count();
}
Is it just bad design choice?
Probably the answer is yes.
And to solve this issue in .NET 4.5 MS introduced IReadOnlyCollection<out T>
interface, which is covariant for reference types.
So you can rewrite your code like following
static int? FastCountOrZero(this IEnumerable items)
{
if (items == null)
return 0;
var collection = items as ICollection;
if (collection != null)
return collection.Count;
var roCollection = items as IReadOnlyCollection<object>; // only for reference types
if (roCollection != null)
return roCollection.Count;
var source = items as IQueryable;
if (source != null)
return QueryableEx.Count(source);
return items.Cast<object>().Count();
}
And as last resort you can cast items
to dynamic object and invoke Count
property dynamicly.
if (items.GetType().GetInterface("System.Collections.Generic.ICollection`1") != null)
{
dynamic dynamic = items;
return dynamic.Count;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With