25 January 2010

A generic convertor for IEnumerable<T>

Apart from ForEach<T>, as I described in my previous post, I noticed the absence of ConvertAll<T> on everything but List<T> as well. Pretty annoying when I wanted to convert a list of business objects of So I extended my static class GenericUtilities with another extension methdo

using System;
using System.Collections.Generic;

namespace LocalJoost.Utilities
{
  public static class GenericExtensions
  {
    // previous code for ForEach omitted.

    public static IEnumerable<TC> ConvertAll<T, TC>(
      this IEnumerable<T> inputList, 
      Converter<T, TC> convert)
    {
        foreach( var t in inputList )
        {
            yield return convert(t);
        }
  }
}
This permitted me to do something like this:
return ListRubriek.Get()
  .ConvertAll(p => new CascadingDropDownNameValue(
        p.Omschrijving, p.Id.ToString()))
  .ToArray();
to easily convert a list of CSLA business objects into a list that could be used in an ASP.NET Ajax Cascading dropdown. Nothing special for the veteran functional programmer I guess but still, useful.

This is actually the 2nd version - thanks to Jarno Peschier for some constructive criticism

2 comments:

  1. Your convert sounds a bit like a generic mapper function, often called map() in functional languages. In .NET this is part of System.Linq as the Select() method. You might be able to use that: simply supply a suitable lamdba that converts from one type to another.

    ReplyDelete
  2. Oh, and another thing: if you define a method returning IEnumerable you are doing more than callers might expect if you construct a List and then return that. It reserves memory for a complete List instance. In your own example you're only interested in an array, so this List is created "in vain".

    I would implement the method using a foreach statement in which you yield return the elements instead of constructing and returning a List. This would give you the same lazy evaluation characteristics as LINQs select: as long as you do not enumerate the sequence nothing is actually done. And the caller can always use ToArray() or ToList() to get an actual collection instance as needed.

    ReplyDelete

Note: Only a member of this blog may post a comment.