tags:

views:

75

answers:

3

Consider this snippet of code:

public static class MatchCollectionExtensions
{
    public static IEnumerable<T> AsEnumerable<T>(this MatchCollection mc)
    {
        return new T[mc.Count];
    }
}

And this class:

public class Ingredient
{
    public String Name { get; set; }
}

Is there any way to magically transform a MatchCollection object to a collection of Ingredient? The use-case would look something like this:

var matches = new Regex("([a-z])+,?").Matches("tomato,potato,carrot");

var ingredients = matches.AsEnumerable<Ingredient>();


Update

A pure LINQ based solution will suffice as well.

+2  A: 

Try something like this (with System.Linq namespace):

public class Ingredient
{
    public string Name { get; set; }
}

public static class MatchCollectionExtensions
{
    public static IEnumerable<T> AsEnumerable<T>(this MatchCollection mc, Func<Match, T> converter)
    {
        return (mc).Cast<Match>().Select(converter).ToList();
    }
}

and can be used like this:

    var matches = new Regex("([a-z])+,?").Matches("tomato,potato,carrot");

    var ingredients = matches.AsEnumerable<Ingredient>(match => new Ingredient { Name = match.Value });
Andrew Bezzub
+2  A: 

You could first cast it...

matches.Cast<Match>()

...and then transform the resulting IEnumerable<Match> however you want using LINQ.

Marcelo Cantos
+3  A: 

Only if you have some way to transform a Match to an Ingredient. Since there isn't a generic way to do this, you'll probably need to give your method a bit of help. For example, your method could take a Func<Match, Ingredient> to perform the mapping:

public static IEnumerable<T> AsEnumerable<T>(this MatchCollection mc, Func<Match, T> maker)
{
  foreach (Match m in mc)
    yield return maker(m);
}

and you could then call this as follows:

var ingredients = matches.AsEnumerable<Ingredient>(m => new Ingredient { Name = m.Value });

You can also bypass creating your own method and just use Select, with the Cast operator to deal with the weak typing of MatchCollection:

var ingredients = matches.Cast<Match>()
                         .Select(m => new Ingredient { Name = m.Value });
itowlson
Option #2 worked. Thanks :)
roosteronacid