Generic extension method returning IEnumerable <T> without using reflection
Consider this piece 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 a way to magically transform a MatchCollection into an Ingredient collection? A usage example would look something like this:
var matches = new Regex("([az])+,?").Matches("tomato,potato,carrot"); var ingredients = matches.AsEnumerable<Ingredient>();
Update
There will also be a fairly clean LINQ based solution.
Only if you have a way to turn a match into a component. Since there is no general way to do this, you will probably have to help your method a bit. For example, to perform a match, your method may take Func<Match, Ingredient> :
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 call it like this:
var ingredients = matches.AsEnumerable<Ingredient>(m => new Ingredient { Name = m.Value }); You can also work around creating your own method and simply use Select, with the Cast operator, to handle the weak MatchCollection:
var ingredients = matches.Cast<Match>() .Select(m => new Ingredient { Name = m.Value }); Try something like this (with the 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 as follows:
var matches = new Regex("([az])+,?").Matches("tomato,potato,carrot"); var ingredients = matches.AsEnumerable<Ingredient>(match => new Ingredient { Name = match.Value });