code_junkie

Howto: Count the items from a IEnumerable<T> without iterating?

Nov 11th, 2011
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.59 KB | None | 0 0
  1. private IEnumerable<string> Tables
  2. {
  3. get {
  4. yield return "Foo";
  5. yield return "Bar";
  6. }
  7. }
  8.  
  9. ICollection<T> c = source as ICollection<TSource>;
  10. if (c != null)
  11. return c.Count;
  12.  
  13. int result = 0;
  14. using (IEnumerator<T> enumerator = source.GetEnumerator())
  15. {
  16. while (enumerator.MoveNext())
  17. result++;
  18. }
  19. return result;
  20.  
  21. BackgroundWorker worker = new BackgroundWorker();
  22. worker.WorkerReportsProgress = true;
  23. worker.DoWork += (sender, e) =>
  24. {
  25. // pretend we have a collection of
  26. // items to process
  27. var items = 1.To(1000);
  28. items
  29. .WithProgressReporting(progress => worker.ReportProgress(progress))
  30. .ForEach(item => Thread.Sleep(10)); // simulate some real work
  31. };
  32.  
  33. using System;
  34. using System.Collections.Generic;
  35. using System.Linq;
  36. using System.Collections;
  37.  
  38. namespace Test
  39. {
  40. class Program
  41. {
  42. static void Main(string[] args)
  43. {
  44. var test = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
  45. var result = test.Split(7);
  46. int cnt = 0;
  47.  
  48. foreach (IEnumerable<int> chunk in result)
  49. {
  50. cnt = chunk.Count();
  51. Console.WriteLine(cnt);
  52. }
  53. cnt = result.Count();
  54. Console.WriteLine(cnt);
  55. Console.ReadLine();
  56. }
  57. }
  58.  
  59. static class LinqExt
  60. {
  61. public static IEnumerable<IEnumerable<T>> Split<T>(this IEnumerable<T> source, int chunkLength)
  62. {
  63. if (chunkLength <= 0)
  64. throw new ArgumentOutOfRangeException("chunkLength", "chunkLength must be greater than 0");
  65.  
  66. IEnumerable<T> result = null;
  67. using (IEnumerator<T> enumerator = source.GetEnumerator())
  68. {
  69. while (enumerator.MoveNext())
  70. {
  71. result = GetChunk(enumerator, chunkLength);
  72. yield return result;
  73. }
  74. }
  75. }
  76.  
  77. static IEnumerable<T> GetChunk<T>(IEnumerator<T> source, int chunkLength)
  78. {
  79. int x = chunkLength;
  80. do
  81. yield return source.Current;
  82. while (--x > 0 && source.MoveNext());
  83. }
  84. }
  85. }
  86.  
  87. .method public hidebysig static int32 Count<TSource>(class 
  88.  
  89. [mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource> source) cil managed
  90. {
  91. .custom instance void System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
  92. // Code size 85 (0x55)
  93. .maxstack 2
  94. .locals init (class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource> V_0,
  95. class [mscorlib]System.Collections.ICollection V_1,
  96. int32 V_2,
  97. class [mscorlib]System.Collections.Generic.IEnumerator`1<!!TSource> V_3)
  98. IL_0000: ldarg.0
  99. IL_0001: brtrue.s IL_000e
  100. IL_0003: ldstr "source"
  101. IL_0008: call class [mscorlib]System.Exception System.Linq.Error::ArgumentNull(string)
  102. IL_000d: throw
  103. IL_000e: ldarg.0
  104. IL_000f: isinst class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>
  105. IL_0014: stloc.0
  106. IL_0015: ldloc.0
  107. IL_0016: brfalse.s IL_001f
  108. IL_0018: ldloc.0
  109. IL_0019: callvirt instance int32 class [mscorlib]System.Collections.Generic.ICollection`1<!!TSource>::get_Count()
  110. IL_001e: ret
  111. IL_001f: ldarg.0
  112. IL_0020: isinst [mscorlib]System.Collections.ICollection
  113. IL_0025: stloc.1
  114. IL_0026: ldloc.1
  115. IL_0027: brfalse.s IL_0030
  116. IL_0029: ldloc.1
  117. IL_002a: callvirt instance int32 [mscorlib]System.Collections.ICollection::get_Count()
  118. IL_002f: ret
  119. IL_0030: ldc.i4.0
  120. IL_0031: stloc.2
  121. IL_0032: ldarg.0
  122. IL_0033: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> class [mscorlib]System.Collections.Generic.IEnumerable`1<!!TSource>::GetEnumerator()
  123. IL_0038: stloc.3
  124. .try
  125. {
  126. IL_0039: br.s IL_003f
  127. IL_003b: ldloc.2
  128. IL_003c: ldc.i4.1
  129. IL_003d: add.ovf
  130. IL_003e: stloc.2
  131. IL_003f: ldloc.3
  132. IL_0040: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
  133. IL_0045: brtrue.s IL_003b
  134. IL_0047: leave.s IL_0053
  135. } // end .try
  136. finally
  137. {
  138. IL_0049: ldloc.3
  139. IL_004a: brfalse.s IL_0052
  140. IL_004c: ldloc.3
  141. IL_004d: callvirt instance void [mscorlib]System.IDisposable::Dispose()
  142. IL_0052: endfinally
  143. } // end handler
  144. IL_0053: ldloc.2
  145. IL_0054: ret
  146. } // end of method Enumerable::Count
  147.  
  148. Tables.ToList<string>.Count
  149.  
  150. using System.Collections.Generic;
  151. using System.Collections.ObjectModel;
  152. namespace HQ.Util.Wpf.WpfUtil.Collections
  153. {
  154. public interface IEnumAndCount<out T> : IEnumerable<T>
  155. {
  156. Count { get; }
  157. }
  158.  
  159. public class ObservableCollectionForFastEnumDerivedCount<T> :
  160. ObservableCollection<T>, IEnumAndCount<T>
  161. {
  162. }
  163. }
Add Comment
Please, Sign In to add comment