Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic extension method returning IEnumerable<T> without using reflection

Tags:

c#

generics

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.

like image 265
cllpse Avatar asked Feb 27 '23 04:02

cllpse


1 Answers

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 });
like image 192
itowlson Avatar answered Mar 01 '23 18:03

itowlson