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:
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.
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.
Post a Comment