2

Is there a way to get an IEnumerable<T> from an IEnumerable without reflection, assuming I know the type at design time?

I have this

foreach(DirectoryEntry child in de.Children)
{
   // long running code on each child object
}

I am trying to enable parallelization, like so

Parallel.ForEach(de.Children, 
    (DirectoryEntry child) => { // long running code on each child });

but this doesn't work, as de.Children is of type DirectoryEntries. It implements IEnumerable but not IEnumerable<DirectoryEntry>.

Community
  • 1
  • 1
Nate
  • 30,286
  • 23
  • 113
  • 184

1 Answers1

6

The way to achieve this is to use the .Cast<T>() extension method.

Parallel.ForEach(de.Children.Cast<DirectoryEntry>(), 
    (DirectoryEntry child) => { // long running code on each child });

Another way to achieve this is to use the .OfType<T>() extension method.

Parallel.ForEach(de.Children.OfType<DirectoryEntry>(), 
    (DirectoryEntry child) => { // long running code on each child });

There is a subtle different between .Cast<T>() and .OfType<T>()

The OfType(IEnumerable) method returns only those elements in source that can be cast to type TResult. To instead receive an exception if an element cannot be cast to type TResult, use Cast(IEnumerable).

-- MSDN

This link on the MSDN forums got me going the right direction.

Nate
  • 30,286
  • 23
  • 113
  • 184
  • 3
    @KooKiz: But pointless if you know that every element is a `DirectoryEntry` anyway. `OfType` filters and casts, so if you need to filter use `OfType` otherwise `Cast`. – Tim Schmelter Oct 31 '12 at 16:45
  • @TimSchmelter Somehow, I always believed that `OfType` was faster than `Cast`. Don't ask me why. Anyway, I've just searched a bit and discovered that `Cast` is faster. So indeed, my remark was pointless. – Kevin Gosse Oct 31 '12 at 16:51