Take a look at the field values of the generated list elements from the second test...
I made a test program from your posted code - got a ten-fold speed improvement. Having a performance profiling tool (check out
Red-Gate.com) I could narrow down where in the conversion function the time was / was not being spent: in your old & new versions of the function, add the following lines right before the
foreach (var item in Source)
loop:
Console.WriteLine("Before: Source.Count: " + Source.Count());
Console.WriteLine("Before: Map.Count: " + Map.Count());
(of course, having 'After' in place of 'Before' where appropriate :)).
I think that'll get you on the way to understanding and fixing your problem.
Totally unrelated..
... and possibly impertinent but possibly helpful: what you're doing, with PropertyDescriptors, is an 'expensive' operation (which you know already). Are you able to require that the source and destination types both implement a common interface (or, simpler, a common abstract base class)?
You wouldn't enforce this constraint in the generic type constraints clause ... but in the static constructor for the class that contains your conversion function (where you would also do, once, any necessary reflection work). Sure, this constraint is enforced at run time, not compile time, but it might
If you can make that constraint you could then also require that the interface requires a Clone() method be implemented - meaning that you'd have no reflection work at all.
Here's a VERY rough idea of the archicture (not compiled, not tested - exists to illustrate the idea):
interface ITransform
{
ITransform Transform(ITransform src);
}
interface ICustomCopyable : ITransform
{
}
class ASource : ICustomCopyable
{
public ITransform Transform(ITransform src)
{
}
}
static class ClonableExtension
{
public static IList<tdest,> DuplicateList(this IEnumerable<tsrc> src, IList<tdest> dst)
where TDest : ICustomCopyable, new()
where TSrc : ICustomCopyable
{
}
}
</tdest></tsrc>