How to get counter from ICollection <T> with unknown T

Here is my code:

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

Is there a good way to get Count from ICollection<T> without resorting to iterating over the collection?

+4
source share
4 answers

A reflection would be correct, but keep in mind that most Collections in FCL inherit from both ICollection<T> and ICollection So code like this works:

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

True is output for both. This works for most, if not all, collections in FCL. If you needed to work with custom collections or collections that do not implement ICollection, then reflection is the only way.

Sidenote: arrays also implicitly implement ICollection, IList, and IEnumerable (the CLR actually generates an array that inherits from common versions of these classes in addition to non-generic at runtime), so your code above will work with arrays as well.

+1
source

Without the private ICollection<T> you need to resort to reflection to call the Count property.

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

You will need to use reflection:

 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); } 
+4
source

Both ICollection and IEnumerable Interfaces have the Count property. Common versions as well.

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

MSDN documentation for ICollection http://msdn.microsoft.com/en-us/library/system.collections.icollection.aspx

MSDN documentation for IEnumerable http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx

-1
source

Source: https://habr.com/ru/post/1383563/


All Articles